I'm looking to get a list of files in a directory in Linux starting with a capital letter. In Unix, it's a simple
ls [A-Z]*
In Linux, though, I'm seeing matches that don't seem to be case-sensitive:
=> ls
A.txt b.txt B.txt c.txt C.txt
=> ls [A]*
A.txt
=> ls [AB]*
A.txt B.txt
=> ls [ABC]*
A.txt B.txt C.txt
=> ls [A-C]*
A.txt b.txt B.txt c.txt C.txt
=> ls [b]*
b.txt
=> ls [a-c]*
A.txt b.txt B.txt c.txt
Running the same commands on the Unix side work as I'd expect. Is this the way Linux has always behaved? It's easy enough to work around this with awk, so I'm not looking for a solution in that way, but I'm wondering if I just never noticed this before. Thanks in advance.
The result depends on different shell options, particularly: nocasematch nocaseglob And also LC_COLLATE variable (used in sort, [-], etc.)
$ shopt extglob nocasematch nocaseglob
extglob off
nocasematch off
nocaseglob off
$ printf "%s\n" a A b B c C | sort
a
A
b
B
c
C
So [A-C] range contains b and c, but not a, also [a-c] should contain A but not C.
$ printf "%s\n" a A b B c C | LC_COLLATE=C sort
A
B
C
a
b
c
gives a different result.
$ LC_COLLATE=C ls [A-C]*
Should return expected result, this syntax sets the variable only for the new process execution (ls), but not in current shell process.
EDIT: thanks to comment, previous command is wrong because the expansion is processed before the LC_COLLATE be set, the simplest is to split into two commands.
$ export LC_COLLATE=C
$ ls [A-C]*
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With