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?

  • 1
    alias ls="ls -h" – Kusalananda Aug 10 '16 at 11:34
  • 2
    AFAIK, GNU ls does not output "human readable" sizes without -h. – Kusalananda Aug 10 '16 at 11:36
  • 1
    it does, with ls -sh. The manual says h, --human-readable: with -l and/or -s, print human readable sizes (e.g., 1K 234M 2G) – ilkkachu Aug 10 '16 at 11:40
  • But the ls on my OS X doesn't support that combination. Don't know about FreeBSD. (Obvious workaround: install GNU ls) – ilkkachu Aug 10 '16 at 11:41
  • 1
    A plain ls -h doesn't display any size whatsoever. Only ls -s and ls -l display sizes. – Gilles 'SO- stop being evil' Aug 10 '16 at 23:06
3

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.

| improve this answer | |
1

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}'
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.