Result of a normal find using find . ! -path "./build*" -name "*.txt"
:
./tool/001-sub.txt
./tool/000-main.txt
./zo/001-int.txt
./zo/id/002-and.txt
./as/002-mod.txt
and when sorted with sort -n
:
./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt
however the desired output is:
./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt
which means output is sorted based on filename only, but folder information should be maintained as part of the output.
Edit: Make example more complicated as the subdirectory structure may include more than one level.
Best Answer
You need to sort by the last field (considering
/
as a field separator). Unfortunately, I can't think of a tool that can do this when the number of fields varies (if onlysort -k
could take negative values).To get around this, you'll have to do a decorate-sort-undecorate. That is, take the filename and put it at the beginning followed by a field separator, then do a sort, then remove the first column and field separator.
That
awk
command says the field separatorFS
is set to/
; this affects the way it reads fields. The output field separatorOFS
is also set to/
; this affects the way it prints records. The next statement says print the last column (NF
is the number of fields in the record, so it also happens to be the index of the last field) as well as the whole record ($0
is the whole record); it will print them with the OFS between them. Then the list issort
ed, treating/
as the field separator - since we have the filename first in the record, it will sort by that. Then thecut
prints only fields 2 through the end, again treating/
as the field separator.