2

With GNU ls one can get "human readable" file sizes (this means suffixes like K, M, G, ... for Kilo-, Mega- and Gigabyte etc. are appended and the number is kept below 1024) with the option -h even if not used in conjunction with -l but only with -s.

How can one get this behavior with the ls that comes with FreeBSD, i.e. how does one get ls -sh to work in FreeBSD?

viuser
  • 2,614

2 Answers2

4

The way to answer this is to read the source code:

No error is reported if -h is given without any of those options.

FreeBSD added the option in 2001, well before the (rather old) userland in OSX. The FreeBSD and OSX manual pages have identical descriptions of -h (and "ls -lh" works for both). But at that point, it only worked with -l:

Add a new flag, -h which when combined with the -l option causes file sizes to be displayed with unit suffixes; Byte, Kilobyte, Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce the number of digits to three or less.

Thomas Dickey
  • 76,765
0

If you want GNU ls features on FreeBSd, you can install the gnuls package and alias ls to gnuls.

If you want to stick to the base software, you can post-process the output of ls. (Script reposted from how do you sort du output by size?) This works on any POSIX system.

CLICOLOR_FORCE=1 ls | awk '
    function human(x) {
        s="kMGTEPYZ";
        while (x>=1000 && length(s)>1)
            {x/=1024; s=substr(s,2)}
        return int(x+0.5) substr(s,1,1)
    }
    {gsub(/^[0-9]+/, human($1)); print}'

CLICOLOR_FORCE causes BSD ls to use colors even if it isn't writing to a terminal. On the other hand, because ls isn't writing to a terminal, you'll get one file per line instead of columns. On FreeBSD, you can use the option -C to get columns, but then the postprocessing script becomes a lot more complex since it needs to find sizes in the middle of the line. Try this (untested):

CLICOLOR_FORCE=1 ls -C | awk '
    function human(x) {
        s="kMGTEPYZ";
        while (x>=1000 && length(s)>1)
            {x/=1024; s=substr(s,2)}
        return int(x+0.5) substr(s,1,1)
    }
    {gsub(/(^|  )[0-9]+/, human($1)); print}'