LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   how do you rename multiple files based on strings in a text file? (https://www.linuxquestions.org/questions/programming-9/how-do-you-rename-multiple-files-based-on-strings-in-a-text-file-4175438669/)

Holering 11-25-2012 01:20 PM

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.

markush 11-25-2012 04:35 PM

Hi,

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".

jschiwal 11-25-2012 08:58 PM

Moved: This thread is more suitable in Programming and has been moved accordingly to help your question get the exposure it deserves.

jschiwal 11-25-2012 09:21 PM

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.

theNbomr 11-27-2012 09:15 AM

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.

--- rod.

Holering 11-29-2012 11:29 AM

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.

markush 11-29-2012 11:50 AM

Code:

#!/usr/bin/perl

use strict ;
use warnings ;
use File::Copy ;
use feature 'say' ;

my $lump ;
my $oggfile ;
my $path = "data\\jdoom\\music\\" ;

open TXTFILE, "textfile.txt" ;
while ( <TXTFILE> ) {
        if ( m/Lump = "([^"]+)".*"(data[^"]+)"/ ) {
                $lump = $path . $1 ;
                $oggfile = $2 ;
        }
        say $lump ;
        say $oggfile ;

        move ( $oggfile, $lump ) ;
}

close TXTFILE ;

textfile.txt is the name of your textfile.

Markus

colucix 11-29-2012 04:01 PM

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?

markush 11-29-2012 04:08 PM

Quote:

Originally Posted by colucix (Post 4839800)
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?

:doh:
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.

Markus

Holering 01-08-2013 10:22 PM

Quote:

Originally Posted by colucix (Post 4839800)
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.


All times are GMT -5. The time now is 09:42 PM.