How to make ls sort by file extension and then name?

46

8

By default the ls command sorts just by filename, but I want directories to appear before other file types. I might even want files to be sorted by extension, like the way Windows explorer sorts by the type column. Is there a way to do something similar with ls?

allyourcode

Posted 2009-08-07T18:23:39.793

Reputation: 578

Answers

44

I think the complete answer is more of a combination of the above.

-X (later --sort=extension) has been supported in Linux since at least FC3 and will sort based on extension. --group-directories-first was added more recently (maybe around FC8?). However, combining the two doesn't seem to work (at least on FC8).

The primary issue seems to be with the use of singular primary sort keys. See this mailing list discussion for some insight into it.

CS

Posted 2009-08-07T18:23:39.793

Reputation:

Yes no problem combining -X / --sort=extension with --group-directories-first and anything else I've tried on modern Linux distros. The OP is referring to Fedora Core 8 (released 2007) so chances are any such problems are in the distant past. – mattst – 2019-03-08T20:42:46.947

5I know this post is rather old, but to others coming here from e.g. Google (like I did): The combination of --sort=extension and --group-directories-first (or only --group-directories) works fine for me on Ubuntu 12.10. Worth a shot on your machine too! =) – Tomas Aschan – 2013-03-29T11:27:28.367

23

On Linux,

$ ls --group-directories-first

(man ls is your friend!)

Ned Deily

Posted 2009-08-07T18:23:39.793

Reputation:

1upvoted IN SPITE of the rtfm comment. – Sridhar Sarnobat – 2016-05-14T22:14:01.087

gls --group-directories-first on Mac if you install GNU Core utils over homebrew – To Kra – 2017-03-01T09:32:34.370

14

-X is the option you're looking for:

ls -lX

Carl Manaster

Posted 2009-08-07T18:23:39.793

Reputation: 291

13

On bash, this will sort of work:

$ ls | rev | sort | rev

From man rev:

 The rev utility copies the specified files to the standard output,
 reversing the order of characters in every line.  If no files are speci-
 fied, the standard input is read.

So 1. ls gives its output, with any flags you want 2. each line is reversed 3. then they're sorted 4. and reversed again 5. like this:

  1. like this:
  2. each line is reversed
  3. then they're sorted
  4. and reversed again So
  5. ls gives its output, with any flags you want

Or, more to the point, as below. They're sorted by last character, then next-to-last, etc. All the .rtf files, for example, are listed together, after a .save file and another file with no extension whose name ends in 'e'. Then come .png files, and so on. This will also work with ls -l, because the extension is normally the last thing on the line (exceptions if you have lines like "tmp@ -> /home/jones/tmp", where links are followed by their targets).

 $ ls | rev|sort|rev
 cslu1
 ls.mp2
 ls.mp3
 ls.mp4
 trees_110214-15
 PAT
 CSLU
 Proxy Form.doc
 finannbyid
 toannbyid
 101209ssi.txt.save
 to_annotate_size
 Matas-time-by-week-integration2.rtf
 cyp3.rtf
 data-dir-scan.perl.doc.rtf
 whence-r21-numid.rtf
 platypus.rtf
 Screen shot 2011-01-21 at 2.17.50 PM.png
 emacs print help.png
 log
 new_month_log
 special
 Google-ngram-critique.html
 perl_path.html
 nl
 DWE_BEN_89808.2.ann
 foo
 d.o.foo
 100811_from_iMac_Documents_in_dock.zip
 to-palikir.zip
 tmp
 file-cleanup
 bar
 data-scan-docs
 cmp-mg-ann-numids
 finished_numids
 to_annotate_numids
 manls.ps
 Mike_address_ticket
 cyp2.out
 cyp3.out
 locate-cyp.out
 manls.out
 DWE_BEN_89808.2.text
 tag2.txt
 l2.txt
 du-h-d3.txt
 finished_ann_numids_110407_1714.txt
 finished_all_numids_110407_1718.txt
 data-dir-scan.perl.doc.txt
 whence-r21-numid.txt
 finannid.txt
 toannid.txt
 b9-workspace-anndiff.txt
 tag.txt
 duh.txt
 d.o-mail.txt
 safextn.txt
 mg3longhdr.txt
 finished_numids.txt
 41692-langnames.txt
 TimeAnnotationGuidelines.txt
 41langs.txt
 thing4-homedir-links.txt
 bnlinks.txt
 grants.txt
 mata-file-reports.txt
 logx.txt
 logx
 b9-workspace-anndiff.txt~
 bnlinks.txt~ 

M. Mandel

Posted 2009-08-07T18:23:39.793

Reputation: 131

+1 for the effort... – varun – 2018-04-03T09:12:28.247

@glennjackman that's better. should be in the answer. – voices – 2018-09-09T02:47:41.707

It would be nice (especially with -F) if piping it through rev & sort didn't strip the colour (-G). – voices – 2018-09-09T02:48:52.297

1Wouldn't list directories first, though. – CarlF – 2011-06-03T21:29:57.737

it will if you ls -F – glenn jackman – 2011-06-04T14:55:34.823

3

If you're running on Linux, GNU ls supports the --sort option:-

ls --sort=extension

DaveR

Posted 2009-08-07T18:23:39.793

Reputation: 139

Not what was asked for. – Sridhar Sarnobat – 2016-05-14T21:05:00.760

3

If you're not on linux,

ls -l |sort -d -k 1.1,1.1r -k 9 |awk '{print $9}'

should sort directories first (let me know if I'm wrong). Doesn't sort by extension, though: you have to make the awk statement a lot busier if you want to do that ...


To also make it work with names containing spaces, I would probably replace the awk with something like sed -E -e 's/([^ ]+[ ]+){8}//' to strip out the first 8 fields instead of printing the 9th

Zac Thompson

Posted 2009-08-07T18:23:39.793

Reputation: 887

1Works on a Mac. Note that if you have CLICOLOR turned on this will remove the coloring. – eykanal – 2011-03-30T14:36:33.553

1will give incorrect results for filenames with spaces. – glenn jackman – 2011-06-04T14:53:18.800

@glenn, you are right ... if this was a concern I would probably replace the awk with something like sed -E -e 's/([^ ]+[ ]+){8}//' to strip out the first 8 fields instead of printing the 9th – Zac Thompson – 2011-06-04T18:29:23.897

ls -l |sort -d -k 1.1,1.1r -k 9 | cut -c 50- – nohillside – 2012-02-10T20:51:46.750

@patrix the filenames are not guaranteed to start on the 50th column. – Zac Thompson – 2012-02-11T20:08:30.090

actually, I'm pretty sure this will work on linux, too, but as others have stated you have some built-in support there. – Zac Thompson – 2009-10-27T05:06:15.810

0

A good approach is separating folders at first, then the sorted files by extensions, by SORTING and REVERSING out:

ls -p | grep /;ls -p | grep -v / | rev | sort | rev

PYK

Posted 2009-08-07T18:23:39.793

Reputation: 101

0

I added to my .bashrc (linux) the line

alias lx = "ls -X"

that way I just type lx and get it sorted by extension.

user192273

Posted 2009-08-07T18:23:39.793

Reputation: 11

Not what was asked for – Sridhar Sarnobat – 2016-05-14T21:05:56.453

@SridharSarnobat I personnally think his answers was totally on topic. And following his suggestion, I have added lx as a bash alias for having ls sorting by file extension and then name: approximately the exact label for this question. – Stephane Rolland – 2020-02-09T08:59:32.120

Does it group directories and files separately? I think that was what I was looking for. – Sridhar Sarnobat – 2020-02-09T17:05:49.050

So the answer to the question is use ls -X :) – Andrew – 2013-01-23T20:23:53.187