I would like to sort directories of files by a specified position in the filename using a "graphical" filemanager.
I have loads of files of this type (e.g.):
0001_oeirnglhk.ext
0002_gkggkcxiuv.ext
0003_xcvxemrn.ext
0004_tteytzpsiogut.ext
0005_sdfdtyeienvf.ext
...
0347_bwvoxciurnsa.ext ↑ └ sort starts hereI would like the sorting to start from Col. 5, that being the first "alpha" character in these strings. My goal is to examine alpha-sort matches (or close matches) while retaining the numerical prefix, then decide on possible manual interventions. I tried doing this by dumping the names to a textfile, then sorting on filenames, but that became very unwieldy at the "interventions" stage, thus the quest for a "gui" solution.
I've poked at this in PCManFM, Nautilus, Nemo, Thunar, and Double Commander, without success. Might there be a plugin, extension, or other app that would do this?
While my ideal is to get a "gui" solution, if there are viable solutions in the terminal, I'd be grateful to know about those, too. For example, if the numerical prefix could be moved temporarily, and restored after the file manipulations are completed, that would work for me too.
Update: While @terdon's neat (and accepted!) solution allowed me to deal effectively with this particular task, it would still be good to know of a graphical file-manager that would sort on an arbitrary "column" of a directory's filenames.
42 Answers
One way to do this would be to rename your files to make them more easily sortable using GUI tools. To test this, I created a few files with ascending numerical prefixes and random names:
for i in {001..005} {150..155}; do n=$(cat /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c 10); touch $i"_"$n.ext;
doneThat created the following files on my system:
$ ls
001_zxUBrPQEEt.ext 003_crMQ1lLrPA.ext 005_t3gf-X2N82.ext
151_aKDwJu7phP.ext 153_SSqGdDLOmO.ext 155_mlnSjEGdCF.ext
002_cmAdbTcm0L.ext 004_-39-uI6G9e.ext 150_Vft6mVa5LN.ext
152_5QNPNYdqDj.ext 154_A3EQG1_idu.extIn order to sort them as you want, it should be enough to move the numerical prefix to the end of the file name. You can do this using the following rename command (to test the name change without actually modifying any names, use -n instead of -v):
$ rename -v 's/^(.+?)_(.*)/$2_$1/' *
001_zxUBrPQEEt.ext -> zxUBrPQEEt.ext_001
002_cmAdbTcm0L.ext -> cmAdbTcm0L.ext_002
003_crMQ1lLrPA.ext -> crMQ1lLrPA.ext_003
004_-39-uI6G9e.ext -> -39-uI6G9e.ext_004
005_t3gf-X2N82.ext -> t3gf-X2N82.ext_005
150_Vft6mVa5LN.ext -> Vft6mVa5LN.ext_150
151_aKDwJu7phP.ext -> aKDwJu7phP.ext_151
152_5QNPNYdqDj.ext -> 5QNPNYdqDj.ext_152
153_SSqGdDLOmO.ext -> SSqGdDLOmO.ext_153
154_A3EQG1_idu.ext -> A3EQG1_idu.ext_154
155_mlnSjEGdCF.ext -> mlnSjEGdCF.ext_155The rename command essentially reads Perl. Here, we are giving it a substitution operator (s/original/replacement/) which it will apply to each file name and rename it to the result of said operator. The regex used will match everything from the beginning of the file name (^) to the first _ ((.*?)_). The ? makes the match non-greedy, forcing it to find the shortest possible matching string. The parentheses "capture" the matched substrings, making them available in the right hand side of the operator. The 1st captured pattern will be $1, the 2nd $2 and so on. The result is that the numerical prefix ($1) is moved to after the rest of the name ($2).
Once you have run this command, you can open the directory and do your thing with the GUI editor. To reverse it and go back to the original names use:
rename 's/(.*)_(\d+$)/$2_$1/' -- *Here, the regex is matching everything up to a _ and then one or more numbers (\d+) until the end of the string ($). The -- at the end is a general feature of many command line programs and it signifies the end of options. That ensures that any file name starting with a - is not mistaken for an option.
A better way is to simply use the sort command from the command line. It has a -k option which allows sorting based on a certain field and a character in this field. A field is a set of characters between two field separators, a whitespace by default. In your case, there is only one field in each filename. Then you need to specify which character in the first field you want to use for sorting. sort counts from 1, so the first letter is a character number six.
You also need to form your file list having one filename per line. This is done by -1 option to ls.
Then the whole work is done by one line:
ls -1| sort -k 1.6
And no file renaming is required.