rename batch files in folder using a textfile

Viewed 62

I have a folder of files that start with specific strings and would like to replace part of their strings using the corresponding column from textfile

Folder with files

 ABC_S1_002.txt
 ABC_S1_003.html
 ABC_S1_007.png
 NMC_D1_002.png
 NMC_D2_003.html

And I have a text file that has the strings to be replaced as:

ABC ABC_newfiles
NMC NMC_extra

So the folder after renaming will be

 ABC_newfiles_S1_002.txt
 ABC_newfiles_S1_003.html
 ABC_newfiles_S1_007.png
 NMC_extra_D1_002.png
 NMC_extra_D2_003.html

I tried file by file using mv

for f in ABC*; do mv "$f" "${f/ABC/ABC_newfiles}"; done

How can I read in the textfile that has the old strings in first column and replace that with new strings from second column? I tried

IFS=$'\n'; for i in $(cat file_rename);do oldName=$(echo $i | cut -d $'\t' -f1);  newName=$(echo $i | cut -d $'\t' -f2); for f in oldName*; do mv "$f" "${f/oldName/newName}"; done ; done

Did not work though.

2 Answers

This might work for you (GNU parallel and rename):

parallel --colsep ' ' rename -n 's/{1}/{2}/' {1}* :::: textFile

This will list out the rename commands for each line in textFile.

Once the output has been checked, remove the -n option and run for real.

For a sed solution, try:

sed -E 's#(.*) (.*)#ls \1*| sed "h;s/\1/\2/;H;g;s/\\n/ /;s/^/echo mv /e"#e' testFile

Again, this will echo the mv commands out, once checked, remove echo and run for real.

Review the result of

sed -r 's#([^ ]*) (.*)#for f in \1*; do mv "$f" "${f/\1/\2}"; done#' textfile

When that looks well, you can copy paste the result or wrap it in source:

source <(sed -r 's#([^ ]*) (.*)#for f in \1*; do mv "$f" "${f/\1/\2}"; done#' textfile)
Related