I have a bunch of directories each containing a bunch of files. Normally I can list all of the files with ls */*.*
but this always lists them according to alphabetical order on the directories, then alphabetical order within each directory. So it will always output
dir1/file1.foo
dir1/file2.foo
…
dir2/file1.foo
dir2/file2.foo
…
…
dirN/file1.foo
dirN/file2.foo
…
What I'd like it to do instead is output it so that the directories are arranged in some specific order (for example, in reverse), but have all the files within each directory in normal order, like so:
dirN/file1.foo
dirN/file2.foo
…
…
dir1/file1.foo
dir1/file2.foo
…
Using ls -r */*.*
doesn't do what I want because it reverses the order within each directory as well as the order of the directories themselves. I have tried using ls `ls -r`
which does what I want for the directory names that have no spaces in them, but won't work for the ones that do (which is unfortunately most of them). If I try instead ls "`ls -r`"
then it outputs the same thing as ls -r
– a list of directory names, but in reverse. How do I get bash to do what I want?
Best Answer
Using the
sort
command:with:
-t '/'
to change the field separator-r
to do a reverse sort-s
to ensure the sort is stable (in other words, it doesn't change order beyond the specified columns-k1,1
to restrict the sort to the first columnThis assumes that the output of
ls */*
is already sorted (which it should be), otherwise add a plainsort
stage in the middle.