0

I have the following list of files in a textfile named files.txt:

./themes/seven/images/list-item-rtl.png
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./xmlrpc.php
./MAINTAINERS.txt
./update.php
./README.txt
./COPYRIGHT.txt
./web.config

I want to sort them by just the filename (sort by the first characters after the last occurrence of the forward-slash). So the above would be output like so:

./COPYRIGHT.txt
./MAINTAINERS.txt
./README.txt
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./themes/seven/images/list-item-rtl.png
./update.php
./web.config
./xmlrpc.php

How do I do this?

3
$ awk -F '/' '{ printf "%s/%s\n", $NF, $0 }' files.txt | sort | cut -d '/' -f 2-
./COPYRIGHT.txt
./MAINTAINERS.txt
./README.txt
./themes/seven/images/arrow-desc.png
./themes/seven/images/arrow-prev.png
./themes/seven/images/fc-rtl.png
./themes/seven/ie7.css
./themes/seven/images/list-item-rtl.png
./update.php
./web.config
./xmlrpc.php

This prepends a copy the filename to the front of the line followed by a / character. The filename is had by taking the last /-delimited field. The last field is $NF in awk.

The output of the awk command is sorted. This sorting will use the /-delimited field added to the front of the line. cut is then used to remove the added /-delimited field.

This approach would work as long as no pathname contains a literal newline character.

There may also be an issue if any of the pathnames end with a / character (possibly the pathname of a directory). These would yield an empty string in the sorting column.

See also: Schwartzian transform

0
0

With GNU awk (gawk) one my specify array traversals:

awk -F'/' 'BEGIN {PROCINFO["sorted_in"] = "@ind_str_asc"} 
           { a[$NF]=$0 }
           END { for ( i in a ) { print a[i] } }' files.txt

In that case: load data into array, indices are defined by the last /-separated field (i.e. filename), elements are the lines of the file. Then traverse array sorted by index value for the printing step.


Basic utils only:

paste <(rev files.txt | cut -d'/' -f 1 | rev) files.txt  | sort | cut -f2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.