I have a directory full of over a thousand files and the names are bit long (and no pattern found in the naming style). I would like to simplify the filenames. E.g.:


.....and so on !

I have made a simple text file (filelist.txt) which reads like this:

1.pdb   Bioimage_23335989_Data_22317866_22317867_20140723_1002.pdb
2.pdb   Bioimage_22335990_Data_22318490_22318491_20140723_1009.pdb
3.pdb   Bioimage_23835970_Data_22317866_22317867_20140723_1005.pdb

.....and so on !

Can anybody provide me with a script (awk, sed, etc) which would read the source file and rename the files accordingly? I could get similar scripts else where but nothing seems to work for me.

  • Shell variable expansions with wildcards and the mv command should be enough to manage this. – HalosGhost Jul 31 '14 at 3:43
  • I don't know if this will help, Mass Rename python script, or another AU user script might help too – No Time Jul 31 '14 at 4:49

No awk or sed necessary, since your filelist.txt is already in the perfect format.

A few things in advance… I presume that there is no whitespace in the file names, and that a space separates the two filenames on each line. Also, I assume that filelist.txt terminates with a EOL before the EOF.

Of course, make a backup of the directory before running this command.

#!/usr/bin/env bash
cd /path/to/pdb_files
while read -r line; do
  mv $line
done < /path/to/filelist.txt


  • while read -r line; do: This iterates through each line of the file, putting each line into the variable $line.
  • mv $line: As each line contains two filenames seperated by a space, we can pass the arguments directly to mv. i.e. it'll immediately move files from the first filename to the second.


I just re-read your question. I interpreted it as you wanting to rename files from (e.g.) 1.pdb to Bioimage_23335989_Data_22317866_22317867_20140723_1002.pdb. I'm not sure if you wanted it the other way around. If so, then the following script would work instead.

#!/usr/bin/env bash
cd /path/to/pdb_files
while read -r line; do
  mv $(awk '{print $2, $1}' <<<$line)
done < /path/to/filelist.txt


*mv $(awk '{print $2, $1}' <<<$line): Read from $line, and print the second field followed by the first field. Pass these two filenames as parameters to mv.

  • I think that mv requires two arguments. – Warwick Jul 31 '14 at 4:23
  • @Warwick, Yep, it does. Each $line has two arguments in it. – Sparhawk Jul 31 '14 at 4:24
  • My bad. I should have checked the input :-) – Warwick Jul 31 '14 at 4:25
  • No worries @user3810095. If it works, please accept. :) – Sparhawk Aug 11 '14 at 13:10
while read tname fname
  mv ${fname} ${tname}
done < filelist.txt

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.