how do you rename multiple files based on strings in a text file?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
how do you rename multiple files based on strings in a text file?
Have a list of ogg music files I'd like to rename based on strings in a text file. Text file looks like this:
Music { ID = "e1m1"; Lump = "D_E1M1"; Ext = "data\jdoom\music\02_Bobby_Prince_-_At_Doom's_Gate.ogg"; }
Music { ID = "e1m2"; Lump = "D_E1M2"; Ext = "data\jdoom\music\03_Bobby_Prince_-_The_Imp's_Song.ogg"; }
Music { ID = "e1m3"; Lump = "D_E1M3"; Ext = "data\jdoom\music\04_Bobby_Prince_-_Dark_Halls.ogg"; }
Music { ID = "e1m4"; Lump = "D_E1M4"; Ext = "data\jdoom\music\05_Bobby_Prince_-_Kitchen_Ace_(And_Taking_Names).ogg"; }
Music { ID = "e1m5"; Lump = "D_E1M5"; Ext = "data\jdoom\music\06_Bobby_Prince_-_Suspense.ogg"; }
Music { ID = "e1m6"; Lump = "D_E1M6"; Ext = "data\jdoom\music\07_Bobby_Prince_-_On_The_Hunt.ogg"; }
Music { ID = "e1m7"; Lump = "D_E1M7"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
Music { ID = "e1m8"; Lump = "D_E1M8"; Ext = "data\jdoom\music\09_Bobby_Prince_-_Sign_Of_Evil.ogg"; }
Music { ID = "e1m9"; Lump = "D_E1M9"; Ext = "data\jdoom\music\10_Bobby_Prince_-_Hiding_The_Secrets.ogg"; }
Music { ID = "e2m1"; Lump = "D_E2M1"; Ext = "data\jdoom\music\12_Bobby_Prince_-_I_Sawed_The_Demons.ogg"; }
Music { ID = "e2m2"; Lump = "D_E2M2"; Ext = "data\jdoom\music\13_Bobby_Prince_-_The_Demons_From_Adrian's_Pen.ogg"; }
Music { ID = "e2m3"; Lump = "D_E2M3"; Ext = "data\jdoom\music\11_Bobby_Prince_-_Intermission_From_DOOM.ogg"; }
Music { ID = "e2m4"; Lump = "D_E2M4"; Ext = "data\jdoom\music\14_Bobby_Prince_-_They're_Going_To_Get_You.ogg"; }
Music { ID = "e2m5"; Lump = "D_E2M5"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
Music { ID = "e2m6"; Lump = "D_E2M6"; Ext = "data\jdoom\music\15_Bobby_Prince_-_Sinister.ogg"; }
Music { ID = "e2m7"; Lump = "D_E2M7"; Ext = "data\jdoom\music\16_Bobby_Prince_-_Waltz_of_the_Demons.ogg"; }
Music { ID = "e2m8"; Lump = "D_E2M8"; Ext = "data\jdoom\music\17_Bobby_Prince_-_Nobody_Told_Me_About_id.ogg"; }
Music { ID = "e2m9"; Lump = "D_E2M9"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
Music { ID = "e3m1"; Lump = "D_E3M1"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
Music { ID = "e3m2"; Lump = "D_E3M2"; Ext = "data\jdoom\music\20_Bobby_Prince_-_Donna_To_The_Rescue.ogg"; }
Music { ID = "e3m3"; Lump = "D_E3M3"; Ext = "data\jdoom\music\21_Bobby_Prince_-_Deep_Into_The_Code.ogg"; }
Music { ID = "e3m4"; Lump = "D_E3M4"; Ext = "data\jdoom\music\09_Bobby_Prince_-_Sign_Of_Evil.ogg"; }
Music { ID = "e3m5"; Lump = "D_E3M5"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
Music { ID = "e3m6"; Lump = "D_E3M6"; Ext = "data\jdoom\music\07_Bobby_Prince_-_On_The_Hunt.ogg"; }
Music { ID = "e3m7"; Lump = "D_E3M7"; Ext = "data\jdoom\music\16_Bobby_Prince_-_Waltz_of_the_Demons.ogg"; }
Music { ID = "e3m8"; Lump = "D_E3M8"; Ext = "data\jdoom\music\22_Bobby_Prince_-_Facing_The_Spider.ogg"; }
Music { ID = "e3m9"; Lump = "D_E3M9"; Ext = "data\jdoom\music\10_Bobby_Prince_-_Hiding_The_Secrets.ogg"; }
Music { ID = "e4m1"; Lump = "D_E4M1"; Ext = "data\jdoom\music\09_Bobby_Prince_-_Sign_Of_Evil.ogg"; }
Music { ID = "e4m2"; Lump = "D_E4M2"; Ext = "data\jdoom\music\20_Bobby_Prince_-_Donna_To_The_Rescue.ogg"; }
Music { ID = "e4m3"; Lump = "D_E4M3"; Ext = "data\jdoom\music\21_Bobby_Prince_-_Deep_Into_The_Code.ogg"; }
Music { ID = "e4m4"; Lump = "D_E4M4"; Ext = "data\jdoom\music\09_Bobby_Prince_-_Sign_Of_Evil.ogg"; }
Music { ID = "e4m5"; Lump = "D_E4M5"; Ext = "data\jdoom\music\16_Bobby_Prince_-_Waltz_of_the_Demons.ogg"; }
Music { ID = "e4m6"; Lump = "D_E4M6"; Ext = "data\jdoom\music\14_Bobby_Prince_-_They're_Going_To_Get_You.ogg"; }
Music { ID = "e4m7"; Lump = "D_E4M7"; Ext = "data\jdoom\music\15_Bobby_Prince_-_Sinister.ogg"; }
Music { ID = "e4m8"; Lump = "D_E4M8"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
Music { ID = "e4m9"; Lump = "D_E4M9"; Ext = "data\jdoom\music\10_Bobby_Prince_-_Hiding_The_Secrets.ogg"; }
Music { ID = "inter"; Lump = "D_INTER"; Ext = "data\jdoom\music\11_Bobby_Prince_-_Intermission_From_DOOM.ogg"; }
Music { ID = "intro"; Lump = "D_INTRO"; Ext = "data\jdoom\music\01_Bobby_Prince_-_Intro.ogg"; }
Music { ID = "bunny"; Lump = "D_BUNNY"; Ext = "data\jdoom\music\23_Bobby_Prince_-_Bunny.ogg"; }
Music { ID = "victor"; Lump = "D_VICTOR"; Ext = "data\jdoom\music\19_Bobby_Prince_-_Victory.ogg"; }
So for example, starting with the last file and going up have the listed *.ogg files renamed to the Lump = "" name in the same line:
"19_Bobby_Prince_-_Victory.ogg" renamed to "D_VICTOR".
next file
"23_Bobby_Prince_-_Bunny.ogg" renamed to "D_BUNNY"
next file
"01_Bobby_Prince_-_Intro.ogg" to "D_INTRO".
and so forth.
How do I tell sed (or something else) to rename every *.ogg file listed in the text file to the "Lump = "blah"" name on the same line (without quotes of course)?
I have many other files and I don't want to manually read each text file and rename every *.ogg file by hand.
an idea would be, that you change the textfile in a way that before and behind the "=" is no space. Then you can source the textfile line by line in a bashscript and use Lump and Ext as variables and use the mv command.
I'll try this, but I'm not very fast at coding
Markus
Edit: I've reporte this thread and asked to move it to "Programming".
You can use wild cards to swallow up the text you don't need, and store the two items you want, recalling that them in the right hand side of a substitute "s" command. Construct a script that will do the renaming.
Code:
sed 's/.*Lump = "\([^"]*\).*Ext = "\([^"]*\)".*/mv "\2" "\1"/;s#\\#/#' file list >script
I'm on my tablet now and haven't tested this solution. You will need to prepend any directory part before data/ or remove the directory path and run the script were the files are. The backslashes hint that the file was produced in Windows. If so, use the "dos2unix" program to check convert the text file first.
The sed command itself uses Ext = " and Lump = " as anchors in the regular expression. The [^"]* matches everything inside the double quotes.
You need to make something clear, here. Do you want to actually rename files, or do you simply want to modify text in a file? If the former, then sed is not the tool for the job, although it could be a useful tool for making the text transformation. If the latter, then sed is probably as good a tool as any, and the fact that the text represents filenames is irrelevant to the problem.
I'm not that advanced of a user and thought this would be easier; I'm not able to follow the previous example. Just to make things more clear I'm trying to rename a list of ogg files I have in a folder (don't want to change the text file!).
I know I can rename multiple files with something like:
# for old in *name.ogg*; do new=`echo $old | sed 's/name.ogg/newname/g'`; mv $old $new; done
But now I'm trying to rename the files using (reading) the text file and using the names from there as well. More specifically, I want to rename every *.ogg file I have listed in the text file and rename it to the Lump = "" string in the text file.
Holering, your list contains duplicate file names with different Lump values. Example:
Code:
Music { ID = "e1m7"; Lump = "D_E1M7"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
Music { ID = "e2m5"; Lump = "D_E2M5"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
or
Code:
Music { ID = "e2m9"; Lump = "D_E2M9"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
Music { ID = "e3m1"; Lump = "D_E3M1"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
What's the desired behaviour in this case? Moreover, please can you clarify if these files are stored into data/jdoom/music/ and if you want them renamed and moved to the current working directory? What about the directory separator? Shouldn't it be / instead of \ if you're working in Linux?
Music { ID = "e2m9"; Lump = "D_E2M9"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
Music { ID = "e3m1"; Lump = "D_E3M1"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
What's the desired behaviour in this case? Moreover, please can you clarify if these files are stored into data/jdoom/music/ and if you want them renamed and moved to the current working directory? What about the directory separator? Shouldn't it be / instead of \ if you're working in Linux?
Code:
my $lump ;
my $oggfile ;
my $path = "data\/jdoom\/music\/" ;
open TXTFILE, "textfile.txt" ;
while ( <TXTFILE> ) {
if ( m/Lump = "([^"]+)".*"(data[^"]+)"/ ) {
$lump = $path . $1 ;
$oggfile = $2 ;
$oggfile =~ s/\\/\//g ;
}
I've adapted my code so that the backslashes become slashes.
Holering, your list contains duplicate file names with different Lump values. Example:
Code:
Music { ID = "e1m7"; Lump = "D_E1M7"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
Music { ID = "e2m5"; Lump = "D_E2M5"; Ext = "data\jdoom\music\08_Bobby_Prince_-_Demons_On_The_Prey.ogg"; }
or
Code:
Music { ID = "e2m9"; Lump = "D_E2M9"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
Music { ID = "e3m1"; Lump = "D_E3M1"; Ext = "data\jdoom\music\18_Bobby_Prince_-_Untitled.ogg"; }
What's the desired behaviour in this case? Moreover, please can you clarify if these files are stored into data/jdoom/music/ and if you want them renamed and moved to the current working directory? What about the directory separator? Shouldn't it be / instead of \ if you're working in Linux?
You're so right!
My mistake; I should've asked how do I copy each file to the name in the text file.
Thanks a lot marcush! Your post looks promising but can your suggestion copy each file to the new name instead of renaming (like colucix said there are multiple names attached to the same lump values). It was my mistake; should've asked how to copy each file to the new names instead.
You guys are great!
P.S.
The directory separator is for Windows; I didn't make the text file.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.