How to find documents in subdirs and also sort them by filename in a solitary command?

Outcome of a regular find making use of 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 also when arranged with sort -n :

./as/002-mod.txt
./tool/000-main.txt
./tool/001-sub.txt
./zo/001-int.txt
./zo/id/002-and.txt

nonetheless the wanted result is :

./tool/000-main.txt
./zo/001-int.txt
./tool/001-sub.txt
./zo/id/002-and.txt
./as/002-mod.txt

which suggests result is arranged based upon filename just , yet folder details need to be kept as component of the result.

Edit : Make instance extra made complex as the subdirectory framework might include greater than one degree.

0
2019-12-02 03:12:00
Source Share
Answers: 3

In zsh ≥ 4.3.10 :

print -l -- **/*.txt~build*(oe\''REPLY=${REPLY:t}'\')
  • **/*.txt matches *.txt in the existing directory site and also its subdirectories recursively.
  • ~build* excludes matches whose message starts with build* (like ! -path './build*'). (You require setopt extended_glob first.)
  • (oe\''…'\') is an arranging glob qualifier. REPLY=… constructs the string to sort from the string to return.
  • ${REPLY:t} is the basename (" tail") of the course.
0
2019-12-03 05:07:11
Source

You require to sort by the last area (taking into consideration / as an area separator). However, I can not consider a device that can do this when the variety of areas differs (so sort -k can take adverse values).

To navigate this, you'll need to do a decorate - sort - undecorate. That is, take the filename and also placed it at the start adhered to by an area separator, after that do a sort, after that remove the first column and also area separator.

find . ! -path "./build*" -name "*.txt" |\
    awk -vFS=/ -vOFS=/ '{ print $NF,$0 }' |\
    sort -n -t / |\
    cut -f2- -d/

That awk command claims the area separator FS is readied to / ; this influences the means it reviews areas. The output area separator OFS is additionally set to / ; this influences the means it publishes documents. The next declaration claims publish the last column (NF is the variety of areas in the document, so it additionally takes place to be the index of the last area) along with the entire document ($0 is the entire document) ; it will certainly publish them with the OFS in between them. After that the checklist is sorted, dealing with / as the area separator - given that we have the filename first in the document, it will certainly sort by that. After that the cut publishes just areas 2 via completion, once more dealing with / as the area separator.

0
2019-12-03 05:05:47
Source

I would certainly make use of documents' - printf' to output name and also course, sort by name, and also cutoff the name in a last action. '###' is simply a pen, to aid reducing.

find -name "*.txt" -printf "%f###%p\n" | sort -n | sed 's/.*###//'

% f publishes the filename, %p the entire course.

I streamlined the find - command to get it right into one line, certainly you would certainly leave the ! -path "./build*" component.

0
2019-12-03 05:05:35
Source