File renaming from list of names contained in another file

I have to rename a large number of files so that the name of each file corresponds to a code number that is given side by side in a list (textfile).
The list contains in column A the filename of the actual files to be renamed and in column B the name (a client code, 9 digits) that has to be assigned to the file.

Listfile:
file-abcd.pdf #to be renamed [tab] 123456789 #the new filename
file-abce.pdf #to be renamed [tab] 809809231 #the new filename
a.s.o

Desired outcome:
file-abcd.pdf --> file.123456789.pdf
file-abce.pdf --> file.809809231.pdf
a.s.o

It's to say "for F in each actual file in files/ named like this on the left, re-name it to the name to the right and keep the old extension... But bash did not understand this phrase :))
The names to be given are stored in a file but the files to name are actual files, so just no idea how to tackle this and where to even start.

So far all the scripting I could do and understand in bash was loops to rename just an extension to a file, or to add an extra suffix. Beginner... sigh... But there has to be a way to do it in Linux, there usually is.
Thanks in advance for your help!

Is it literal contents of the file containing filenames?

file-abcd.pdf #to be renamed [tab] 123456789 #the new filename
file-abce.pdf #to be renamed [tab] 809809231 #the new filename

Or is it just:

file-abcd.pdf      123456789
file-abce.pdf      809809231 

Anyway if your file looks like that second example, then this should work:

awk '{f=$1;sub("-.*\\.","."$2".",$1);system("mv "f" "$1)}' file-with-filenames
1 Like

Assuming the listfile and the pdf files are in the same directory and you being there:

$ awk '{print $1" "$5}' listfile | while read fn id; do
mv -v "$fn" "$(echo $fn|sed 's/pdf//')$id.pdf"
done
file-abcd.pdf -> file-abcd.123456789.pdf
file-abce.pdf -> file-abce.809809231.pdf
$ 
for i in `cat listfile`
do
orgfilename=`echo $i | awk '{print $1}'`
newfilename=`echo $i | awk 'print $5}'`
mv $orgfilename $(echo $orgfilename | sed s/pdf/$newfilename\.pdf/g)
done

Anyway if your file looks like that second example, then this should work:

awk '{f=$1;sub("-.*\\.","."$2".",$1);system("mv "f" "$1)}' file-with-filenames

[/quote]

1/ thanks!

2/ yes, the file looks like in the second example, it is a simple copy-paste of two columns from a spreadsheet to a text file.

3/ however, there is a small issue - caused by my attempt to keep the example simple; in fact the files have longer names with lots of dahses in them "-" like so:
acme-doc-may-00101.pdf 2336909
acme-doc-may-00102.pdf 2336910
acme-doc-may-00103.pdf 2336911

some are even longer
acme-doc-may-bclot-00104.pdf 2336912

Apologies, I wanted to keep it all lean in the example.

this causes a little problem, the renamed files have an extra dot in the filename after running your command:
acme.2336909.pdf
acme.2336910.pdf
acme.2336911.pdf

In other operating systems it would be a problem to have two dots, so best to have an underscore instead.
I tried to edit your command but messed up results, of course :slight_smile:

many thanks indeed!!!

This should work:

awk '{f=$1;sub("-.*\\.","_"$2".",$1);system("mv "f" "$1)}' file-with-filenames
1 Like

works like a charm!

very subtle! it replaces the dashes with underscore and renames the files with the number supplied in the right column.
many, many thanks!!!

may I ask you what the "system" command or call does? is it like $(command)?
anyway, thank you, very grateful.

No problem ;). As for "system", it is AWK function for calling external commands.