1

I have several hundred files, all with names following the same template :

results_20210503_input003_run017_cluster003.txt

Is their en efficient way in bash to reorder the substrings ?

results_input003_cluster003_run017_20210503.txt

I'm thinking of using cut -f$i to get each field and then use mv to rename the files, but that looks clunky.

TGIBear
  • 13

2 Answers2

2

Use the Perl's rename commandline tool (depending on your operating system, that might be called rename or perl-rename or prename):

rename 's/(results)(_[0-9]{8})(.*)(\.txt)/$1$3$2$4/' results*txt

Use the -n-flag for a dry run showing you the renames.

How it works:

  • s/A/B/ - substitute pattern A with pattern B in filenames
  • Patterns in parentheses are given an index number as they appear
  • Groups are: 1) results: literaly "results" ; 2) _[0-9]{8}: underscore followed by 8 digits from 0 to 9 ; 3) .* .=any character, *=repeat previous entry as much as possible, i.e. a series of any character ; 4) \.txt literally ".txt", . needs to be escaped, otherwise would be "any character" as in (3)
  • Reorder the pattern groups as desired, reference by $<ID>
FelixJN
  • 13,566
  • Needed to modify a bit because it doesn't give the order I wanted, but worked after a tweak : rename -n 's/(.+)(_.+)(_.+)(_.+)(_.+)(\.txt)/$1$3$5$4$2$6/' – TGIBear May 04 '21 at 14:46
  • Indeed my fault for overlooking the position change of "clusterXXX". Sorry. – FelixJN May 04 '21 at 18:26
0

You don't mention your OS so it's hard to guess what tools may be available to you. I find mmv simplest for cases like this. It uses shell globs rather than regular expressions:

$ mmv -n 'results_*_*_*_*.txt' 'results_#2_#4_#3_#1.txt'
results_20210503_input003_run017_cluster003.txt -> results_input003_cluster003_run017_20210503.txt

Remove the -n when you are satisfied with the proposed re-namings.


If you really have to do it "in bash", then

for f in results_*.txt; do 
  IFS=_ read -a elems <<<"${f%.txt}"
  echo mv -n "$f" "results_${elems[2]}_${elems[4]}_${elems[3]}_${elems[1]}.txt"
done
mv -n results_20210503_input003_run017_cluster003.txt results_input003_cluster003_run017_20210503.txt

Remove the echo to actually rename the files.

steeldriver
  • 81,074
  • Sorry, I should have mentionned it. I'm on Ubuntu, but not on my own machine. Though it requires installing a new tool, I'll keep in mind that mmv exists. Thanks. – TGIBear May 04 '21 at 14:48