20
$ ls |sort
xyz-0.0.1-1554490900.rpm
xyz-0.0.1-1554745305.rpm
xyz-0.0.1-1554751021.rpm
xyz-0.0.1-1555513460.rpm
xyz-0.0.1-1555951745.rpm
xyz-0.0.1-1554323568.rpm

$ /bin/ls |sort
xyz-0.0.1-1554323568.rpm
xyz-0.0.1-1554490900.rpm
xyz-0.0.1-1554745305.rpm
xyz-0.0.1-1554751021.rpm
xyz-0.0.1-1555513460.rpm
xyz-0.0.1-1555951745.rpm

$ which ls
alias ls='/bin/ls --color'
        /bin/ls

Note that the sorting is different between the two commands (ls |sort results in incorrect sorting). This must be due to the color flag, but why?

2
  • 1
    To sort the output of ls, in many cases, you may found useful to specify directly the -v option: ls -v . Better to avoid the deprecated and risky parsing of its output... In many modern distributions the alias of ls is directly set to /bin/ls --color=auto, as they suggest you in an answer.
    – Hastur
    Apr 23, 2019 at 10:24
  • 1
    The thing you're missing is how ANSI colour codes are signalled in a terminal. I'm not sure if it's constant or varies between terminals, but for me red can be triggered by printing \033[91m. Once you imagine the colour codes that are output by ls (normally consumed by the terminal), you can see why your sort would break (and then, the terminal strips them out so you can't see why the sort broke). I'm guessing the results were grouped by colour, then sorted by name?
    – Basic
    Apr 23, 2019 at 19:28

2 Answers 2

24

Do:

/bin/ls --color > file1
/bin/ls > file2

and compare content, you'll see the difference.

Aliasing ls to /bin/ls --color=auto is likely better idea, it will stop ls from using color codes when not writing directly to terminal (like when piping to next program or writing to a file).

7
  • 16
    @JoshM. Well, sorting should be done by ls itself, if possible. Sorting with sort is parsing, not recommended in general. Apr 22, 2019 at 19:43
  • 6
    @JoshM., rather than using /bin/ls, change your alias to what Tomak suggested and you will get the better behavior automatically.
    – John1024
    Apr 22, 2019 at 19:46
  • 5
    @JoshM. You can also use \ls for an unaliased ls or command ls for /bin/ls.
    – Freddy
    Apr 22, 2019 at 19:58
  • 10
    Yes, @Freddy, very true. But, using alias ls='/bin/ls --color' is just a recipe for trouble.
    – John1024
    Apr 22, 2019 at 20:00
  • 1
    How does this answer answer the OP's question?
    – pts
    Apr 24, 2019 at 8:12
25

In the sorted colored output ls|sort, we can see that the last line xyz-0.0.1-1554323568.rpm is the first line of the non-colored output. The other lines are sorted equally.

If we have at a look at the colored escape codes (non-sorted), we can see that the first line starts with a different escape code ^[[0m. This is causing the wrong order when sorted (^[[01 before ^[[0m).

$ /bin/ls --color xyz* | cat -A
^[[0m^[[01;31mxyz-0.0.1-1554323568.rpm^[[0m$
^[[01;31mxyz-0.0.1-1554490900.rpm^[[0m$
^[[01;31mxyz-0.0.1-1554745305.rpm^[[0m$
^[[01;31mxyz-0.0.1-1554751021.rpm^[[0m$
^[[01;31mxyz-0.0.1-1555513460.rpm^[[0m$
^[[01;31mxyz-0.0.1-1555951745.rpm^[[0m$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .