Take the 2-minute tour ×
Ask Different is a question and answer site for power users of Apple hardware and software. It's 100% free, no registration required.

How can I make the ls command in Max OS X Lion sort files and directories similar to how Ubuntu Linux does (case-insensitive, directories NOT on top, dot files NOT on top)? Ideally I'd like to do this without piping output to another command such as sort.

For example, I want to see:

foo
Foobar
MyStuff/
.stuff/
test.txt

instead of:

.stuff
Foobar
MyStuff/
foo
test.txt

In Linux, ls sort order is controlled by the system's locale, specifically LC_COLLATE. When LC_COLLATE=en_US.UTF-8, ls will sort items like I want. When LC_COLLATE=C, ls will sort similar to OS X.

LC_COLLATE is set to en_US.UTF-8 in OS X, but ls still sorts the old POSIX way. Does anyone know how I can make this behave more like Linux?

share|improve this question

migrated from serverfault.com Dec 18 '11 at 7:09

This question came from our site for professional system and network administrators.

    
If it helps: apple.stackexchange.com/a/22304/8546 observes that HFS Plus is usually configured to be case insensitive but case preserving. –  Graham Perrin Feb 14 '13 at 19:43

9 Answers 9

Run:

$ type ls

You'll probably find that your ls command is aliased.

share|improve this answer
    
On linux: ls is /bin/ls. On OS X: ls is hashed (/bin/ls). Either way, even if I call /bin/ls directly it still doesn't sort according to LC_COLLATE. –  blt04 Oct 13 '11 at 22:37
2  
That's surprising, I would have wagered that your ls command was aliased to include --group-directories-first. It may still be done somewhere else, just not an alias. –  MikeyB Oct 13 '11 at 23:08

If you are mainly concerned with the sort order of the dot files, you can sort by extension: Use the ls command from the GNU Fileutils with the option --sort=extension. (You can install the GNU Fileutils e.g. through macports.)

share|improve this answer

As a workaround you can use a function and an alias:

function lssorted() { /bin/ls "$@" | sort -f ;}
alias ls='lssorted'

This produces a case insensitively sorted output for the standard ls command.

share|improve this answer
1  
I have to note: this will fail if for example -l is used. Then ls produces another line "total X" at the beginning, which will also be sorted. –  Arne Dec 22 '11 at 8:51

It might not be possible:

Taking a look at the source code for ls, it uses strcoll to sort the filenames, and so should respect LC_COLLATE.

Some postings online suggest that the locales in BSD (and Darwin/OS X) are somewhat broken compared to those in Linux. I wrote a quick sorting program of my own which explicitly set it's locale and tested it using both the en_US.UTF-8 and C locales on my machine (Mac OS 10.6.3) and a university machine (Linux, FC11?). While sorting works as expected on the linux machine, ("a B c" vs "B a c"), the mac always sorts them as "B a c".

Source: http://ask.metafilter.com/130292/CaseInsensitive-LS-on-Mac-OS-X

ORIGINAL ANSWER

This command does not sort dot files, but shows additional directory listings

ls -f1 

I got close to this:

.
..
.stuff
foo
Foobar
MyStuff
test.txt
share|improve this answer
    
Interesting that "disabling sort" with the -f option actually seems to sort it as expected. I assume this is the filesystem/HFS+ sorting entries with a more "natural" collation. –  Gerry Feb 15 '13 at 13:42

This has been bugging me for awhile now, and I finally got it sorted (heh). After trying a bunch of suggestions that didn't work, here's what did.

If you're willing to install MacPorts (or Homebrew, or Fink), the GNU version of ls does exactly what you want. I use MacPorts, myself, so that's the approach I'll explain:

  1. Download and install MacPorts:

    http://www.macports.org

  2. Install the GNU Coreutils package:

    sudo port install coreutils

  3. You should now have GNU ls: gls. Try it in a directory that contains items that start with both uppercase and lowercase letters:

    gls -U

    (The -U option actually means "unsorted", but on OS X that has the desired effect of making it case insensitive.)

  4. Add this alias in your .bash_profile so the regular ls will work the way you want it to (I like the color output, but you can omit that if you want; you only need the -U):

    alias ls='gls -U --color'

Note that the -U option probably won't work on other platforms. In OS X, it always seems to do the right thing (maybe because HFS+ is effectively case-insensitive -- "case-aware", technically), but if you try it on a Linux box, the results will most likely just not be sorted at all.

share|improve this answer

I know this has been answered but this work best for me:

ls -f1 -alF -G

It lists all details and sorts them by ignoring case.

share|improve this answer

ls is sorting according to LC_COLLATE, it's just that most all of the LC_COLLATE files are set to do case sensitive sorting. http://collation-charts.org/fbsd54/

There are two that are set for case insensitive sorting: cs_CZ.ISO8859-2 and et_EE.ISO8859-15 et_EE.ISO8859.15 doesn't sort "Z" the way english speakers would want. cs.CZ.ISO8859-15 does a good job with the alphabet, I just wish it would sort "~" before alphabetic characters.

My solution is: LC_COLLATE=cs_CZ.ISO8859-2 /bin/ls -FG

I wonder if a custom LC_COLLATE file could be made to handle "." the way you want and "~" the way I want.

share|improve this answer

Using

ls -f

works for me.

-f officially switches off any sorting, but it looks like then the original HFS sort shines through, which is exactly a case-insensitive sort.

I guess, it actually depends on whether you have your HD formated case-sensitive or not, but as case-INsensitive HFS format is the default for Mac OS X system disks, this should work for the majority of users.

share|improve this answer
    
This is definitely the right answer. The only issue with it is that it implicitly turns on -a as well, and there's no way to turn that off, which will show you files/folders beginning with a period, including . and .. . –  lensovet Dec 12 at 0:12

Adding to what Mike wrote above, I've taken it a bit further and found a way to define your own collation rules.

The locale definitions are located in /usr/share/locale/. Each folder is a locale and has a file (or a link) LC_COLLATE, which defines which symbols are "same" (for example, that U, u and ü should be considered the same when ordering). You can duplicate a directory and this will create a new locale definition:

$ sudo cp -R en_GB.UTF-8/ en_GB.UTF-8-CI/

Now you'll have a new locale called 'en_GB.UTF-8-CI' ('CI' for case-insensitive) and you can use LC_COLLATE from there.

Now, to change LC_COLLATE in the new locale you can download the locale sources from http://www.opensource.apple.com/source/adv_cmds/adv_cmds-119/usr-share-locale.tproj/colldef/, edit the one that's closest to what you want and run

$ colldef < <new collation file>
$ sudo cp LC_COLLATE /usr/share/locale/en_GB.UTF-8-CI/

and now when you run

$ LC_COLLATE=en_GB.UTF-8-CI ls

you will have sorting according to your rules.

Yes, this is what it takes to make 'ls' sort case-insensitive.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.