171

Can you sort an ls listing by name?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Devang Kamdar
  • 5,617
  • 8
  • 24
  • 16
  • 13
    If it's not sorting by name without any arguments, you might want to check if ls has been aliased to something else, or simply invoke it using the full path which would eliminate any aliases that exist. – tvanfosson May 18 '09 at 15:23
  • gnu-coreutils ls sorts by default. What system are you using (as other have asked) – Nick Fortescue May 18 '09 at 15:32
  • Are you sure your asking to sort by name and not by type (ie. directory first then files)?? – curtisk May 18 '09 at 16:24
  • 1
    Capital letters come before lowercase letters, thus file Z comes before file a... how can I fix that? – ArtOfWarfare Oct 01 '13 at 19:12
  • 1
    man page says 'sorted separately and in lexicographical order'. Files are sorted according to the first character: numerical [0..9] and UPPER characters [A..Z] and lowe characters [a..z] – Gürol Canbek May 28 '16 at 20:05
  • @tvanfosson how do I check that? –  May 12 '18 at 21:31
  • 1
    @user770 use the "alias" command (without any arguments) to list any aliases that you've set up, https://en.wikipedia.org/wiki/Alias_(command) – tvanfosson May 13 '18 at 19:53
  • @tvanfosson this printed no output and confirmed my issue (capital letters take precedence). Thanks :) –  May 13 '18 at 20:04

14 Answers14

149

My ls sorts by name by default. What are you seeing?

man ls states:

List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Evert
  • 93,428
  • 18
  • 118
  • 189
  • `ls` doesn't sort if `-c1` specified: is there a way to get it to do so? (`--sort=name` doesn't seem to work) – dhc Jan 16 '15 at 19:01
  • 5
    That is not true. with `ls -la`, i see: `.bashrc - can - .config - Downloads - .local - tmp`, sort be name would be: `.bashrc - .config - .local - Downloads - can - tmp` – 12431234123412341234123 Aug 14 '17 at 10:15
  • 1
    mine says 100.jpg comes before 10.jpg. Makes sense I guess if "0" comes before "." but its still not intuitive – chiliNUT Nov 22 '17 at 15:58
  • I'm seeing "M" before "b". Confused. Wait, does capitalisation matter? –  May 12 '18 at 21:37
  • @dhc – `ls -c1` sorts by creation time (the last change to an inode, _not_ birth time), newest to oldest, in a single column. `ls -cl` loses that sort order unless you use `ls -clt`. If you don't want to sort by creation time, don't use `-c` without `-l`. – Adam Katz Oct 10 '21 at 19:15
  • I'm seeing `_` come before `1` despite the fact that this is not properly ASCII sort order. I'm also seeing inconsistency based on whether or not there is a file extension (e.g. "A" comes before "A1" but "A.jpg" comes *after* "A1.jpg)!!! – Michael Feb 07 '22 at 18:30
  • @Michael it's not based on an ascii sort, it's based on collation in the locale. – Evert Feb 07 '22 at 18:45
  • Yes, /bin/ls should default to sorting by name, according to the man page. I actually noticed a specific (small) bug in /bin/ls on a PopOS machine, but it behaves correctly on an Ubuntu machine. It's in a test suite for my Fexl project so I'll just link to the comment here: https://github.com/chkoreff/Fexl/blob/b0854ee62a5dfdce88453d0925dfbfb2bf6c6e94/src/test/b14.fxl#L15 – Patrick Chkoreff Feb 09 '23 at 13:39
146

For something simple, you can combine ls with sort. For just a list of file names:

ls -1 | sort

To sort them in reverse order:

ls -1 | sort -r
shaedrich
  • 5,457
  • 3
  • 26
  • 42
Mark
  • 1,763
  • 1
  • 12
  • 6
  • 3
    Is there a way to sort files like this: `ls | sort -n` _1.1.1; 1.1.2; 1.1.3; 2.10.1; 2.10.15; 2.10.2; 2.10.20; 2.10.21; 2.1.1; 2.1.10; 2.1.15; 2.1.2; 2.1.3; 2.1.4; 10.1.1; 10.1.2; 10.1.3; 11.0.1; 11.0.2; 11.0.20; 11.0.21; 11.0.22;_ As you can see **2.10.15 before 2.10.2**. – BBK Feb 14 '14 at 13:15
  • I'm doing some android development on a Pidion device, and ls doesn't automatically sort, so this was very helpful! The only problem is that it looks like it sorts soft links but doesn't sort files, for some reason – Mitch Dec 16 '14 at 14:32
  • 2
    On Mac, it looks like that second command can be shortened to `ls -1r`. – Ash Ryan Arnwine Jun 01 '16 at 14:51
  • 6
    @BBK sort -V will sort by version numbers, so you get .. 2.10.2; 2.10.15; .. from man sort .. --sort=WORD will sort according to WORD: general-numeric -g, human-numeric -h, month -M, numeric -n, random -R, version -V – mosh Jan 21 '18 at 15:21
  • I recently noticed on one machine that "ls -1" was returning names out of order in some cases. For example: $ ls -l tmp read_csv.fxl read.fxl read_ssv.fxl That's clearly out of order because "." < "_", so read.fxl would appear first if sorted. I'm a little surprised that /bin/ls doesn't have an option which simply means "sort by name". Note that I'm using "ls - 1", as in the numeral ONE, and not "ls -l", which does sort by name. – Patrick Chkoreff Feb 09 '23 at 13:10
51

ls from coreutils performs a locale-aware sort by default, and thus may produce surprising results in some cases (for instance, %foo will sort between bar and quux in LANG=en_US). If you want an ASCIIbetical sort, use

LC_ALL=C ls
Richard Smith
  • 13,696
  • 56
  • 78
  • `LANG` ilfnuence the sort behavior, this post help me a lot! – yurenchen Jun 21 '16 at 07:40
  • This worked for me as well. could you elaborate on this? Why does it sort differently? – Kostas Dec 28 '16 at 13:07
  • 3
    This dose work, but output `?` for every non-ascii character when the output is a terminal (bad feature from ls do check if it output to a terminal, work when piping). You can "fix" this with piping to cat, use the `C.UTF-8` locale (if your system supports it) and/or use the `-b` flag. Even better, do not use `ls` at all, better use ` – 12431234123412341234123 Sep 05 '17 at 16:36
  • This helped me to discover that for me, the problem was that some of my filenames contained a hyphen (-), and some an en dash (–). `ls` sorts hyphens before en dashes. – Jamy Mahabier Feb 04 '20 at 01:19
  • 1
    I had to set `LC_ALL=C` for this to work, as it is suggested in the [ls documentation](https://www.gnu.org/software/coreutils/ls). Changing LANG or LC_COLLATE as per [this answer](https://stackoverflow.com/a/51504065/7498073) did'nt work for me (GNU coreutils 8.32). – zazke Jul 07 '22 at 05:57
27

The beauty of *nix tools is you can combine them:

ls -l | sort -k9,9

The output of ls -l will look like this

-rw-rw-r-- 1 luckydonald luckydonald  532 Feb 21  2017 Makefile
-rwxrwxrwx 1 luckydonald luckydonald 4096 Nov 17 23:47 file.txt

So with 9,9 you sort column 9 up to the column 9, being the file names. You have to provide where to stop, which is the same column in this case. The columns start with 1.

Also, if you want to ignore upper/lower case, add --ignore-case to the sort command.

luckydonald
  • 5,976
  • 4
  • 38
  • 58
user491575
  • 563
  • 1
  • 6
  • 6
  • 3
    What does `-k9,9` mean? – luckydonald Dec 06 '17 at 07:43
  • 1
    Found out, it means to sort column `9` up to the same column `9`. A normal `ls` output looks like this: ```drwx------ 8 999 user 4.0K Feb 5 2017 file.txt```, so column 9 being the file names. If you want to ignore the case, use `--ignore-case` on sort. – luckydonald Dec 06 '17 at 07:48
17

Files being different only by a numerical string can be sorted on this number at the condition that it is preceded by a separator.

In this case, the following syntax can be used:

ls -x1 file | sort -t'<char>' -n -k2

Example:

ls -1 TRA*log | sort -t'_' -n -k2

TRACE_1.log
TRACE_2.log
TRACE_3.log
TRACE_4.log
TRACE_5.log
TRACE_6.log
TRACE_7.log
TRACE_8.log
TRACE_9.log
TRACE_10.log
Patrick Mevzek
  • 10,995
  • 16
  • 38
  • 54
poney
  • 181
  • 1
  • 2
8

NOTICE: "a" comes AFTER "Z":

$ touch A.txt aa.txt Z.txt 

$ ls

A.txt Z.txt aa.txt

shaedrich
  • 5,457
  • 3
  • 26
  • 42
russian_spy
  • 6,465
  • 4
  • 30
  • 26
  • 4
    This is not always true. I don't exactly know the circumstances that make this not true, but on my machine running Ubuntu 12.04 the output of ls is sorted alphabetically (ignoring case). – Patrick James McDougle Jan 03 '13 at 14:43
  • Good catch! Seems like it is ordering it based on the ASCII code.. Upper case alphabets are followed by lowercase.. – Kent Pawar Apr 11 '13 at 08:08
  • 1
    I noticed that my MacOS sorts first numbers, then uppercase letters, then underscore and then lowercase letters. It's funny that they are not case sensitive. On the other hand, my Debian is case sensitive but it sorts the letters insensitively unless there is a tie, then lowercase wins! Example: ABA.txt ABb.txt aBC.txt AbC.txt ABc.txt – zk82 Dec 15 '16 at 15:53
  • I'm on a MAC too. i was disappointed to see the A,Z,a,z type of sorting. I'm here because I prefer to have A,a,Z,a. thanks for your tip. will try out the `normal` solutions here. – nyxee Feb 22 '17 at 07:59
4

From the man page (for bash ls):

Sort entries alphabetically if none of -cftuSUX nor --sort.

jwoolard
  • 6,024
  • 9
  • 37
  • 37
3

The ls utility should conform to IEEE Std 1003.1-2001 (POSIX.1) which states:

22027: it shall sort directory and non-directory operands separately according to the collating sequence in the current locale.

26027: By default, the format is unspecified, but the output shall be sorted alphabetically by symbol name:

  • Library or object name, if −A is specified
  • Symbol name
  • Symbol type
  • Value of the symbol
  • The size associated with the symbol, if applicable
Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743
3

ls -X works for that purpose, in case you have aliased ls to a more useful default.

jezzo
  • 193
  • 10
2

Check your .bashrc file for aliases.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sujit
  • 2,403
  • 4
  • 30
  • 36
2

You can try:

ls -lru

-u with -lt: sort by, and show, access time;

Avtar Sohi
  • 295
  • 3
  • 4
0
In Debian Jessie, this works nice:

ls -lah --group-directories-first

# l=use a long listing format
# a=do not ignore entries starting with .
# h=human readable
# --group-directories-first=(obvious)
# Note: add -r for reverse alpha

# You might consider using lh by appending to ~/.bashrc as the alias:
~$ echo "alias lh='ls -lah --group-directories-first'" >>~/.bashrc
# -- restart your terminal before using lh command --
0
ls | sort -V

will sort nicely if you have numbered files, e.g.

File-8.webvtt
File-9.webvtt
File-10.webvtt
File-11.webvtt
Vladtn
  • 2,506
  • 3
  • 27
  • 23
-1

I got the contents of a directory sorted by name using below command:

ls -h

Rohit Gaikwad
  • 3,677
  • 3
  • 17
  • 40
  • 2
    `ls` without any options already sorts by name, `-h` just prints stuff like sizes in "human readable" form. – Michael Feb 07 '22 at 18:27