[BASH][HELP] Can someone help me write a script to rename files? - Programming On Unix

Users browsing this thread: 1 Guest(s)
neo1691
Members
So I have a directory with 22 .avi files whose names are like this:

The Mentalist Season 1 E(1).avi
The Mentalist Season 1 E(2).avi

and so on and so forth.

So I would like to change them to
The Mentalist S01E01.avi
The Mentalist S02E02.avi

and so on and so forth.

Looking at the problem programatically, I can see the followings steps to arrive at the solution.

1) Process all the files unless there are no more files.
1.1) Find out the number after Season and save it in a variable called $Season.
1.2) Find out the number after E( and save it in a variable called $Episode.
1.3) execute "mv $file The Mentalist S"$Season"$Episode".avi
1.4) done
2 Exit

So can someone tell me how can I arrive on the solution using shell scripting for now?

One small request is please don't give me direct answer, just point out what linux utilities should I use to come up with the solution. I would like to struggle with it myself.

I would have probably renamed those 20 avi files myself my now, but now I have decided to automate everything myself!!

Also tvnamer is not working with the format of the files.
venam
Administrators
Use find with -iname to use a regex to get all the files you want.

Then add a -exec at the end of find to mv the file.

That would look like:
Code:
find location -maxdepth 1 -iname "regex here" -exec mv {} $(subquery here) \;

And the subquery would do the following:
Code:
The Mentalist Season 1 E(1).avi
Replace "eason " by "0" or nothing depending on how you want it.
Code:
The Mentalist S1 E(1).avi
Replace" E(" by "E", and ")" by nothing.
Code:
The Mentalist S1E1.avi

The hard part it to replace 1 digits number by 0 concatenated with the number.
neo1691
Members
Okay,
but find . -maxdepth 1 -iname "some regex" will only find the names of files matching the regex right? the only files in the folder are the 22 files, with nothing else. I think that I don't need to use the "find" command. An if loop with a condition that the file ending in .avi should suffice.

The hard part is for me how to extract the numbers from the string.
z3bra
Grey Hair Nixers
Can be done with a for loop, using a bit of extracting with sed, and formatting with printf :)

Try to do it as an exercise !

extract the season number using sed, same for the episode. then use printf to create a new name for your file.

Then move the old name to the new name !

Code:
#!/bin/sh

for f in *.avi; do
    season=$(echo "$f" | sed 's/^.*Season \([0-9]*\).*$/\1/')
    episod=$(echo "$f" | sed 's/^.*E(\([0-9]*\).*$/\1/')
    name=$(printf "The_Mentalist_S%02dE%02d.avi" $season $episod)
    mv "$f" "$name"
done

exit 0
neo1691
Members
Great, I will work on it. and then compare it with the code you have given. I haven't clicked on the show button yet!
z3bra
Grey Hair Nixers
Do as you wish, but baking your own solution will teach you far more things than actually copying it ;)
neo1691
Members
Great, I will work on it. and then compare it with the code you have given. I haven't clicked on the show button yet!
(06-09-2014, 07:42 AM)z3bra Wrote: #!/bin/sh

for f in *.avi; do
    season=$(echo "$f" | sed 's/^.*Season \([0-9]*\).*$/\1/')
    episod=$(echo "$f" | sed 's/^.*E(\([0-9]*\).*$/\1/')
    name=$(printf "The_Mentalist_S%02dE%02d.avi" $season $episod)
    mv "$f" "$name"
done

exit 0

I have to give up with sed.
I mean I looked up into it, but I clearly need to understand more about it.
Can you explain those regex to me?

Edit: To be more clear I was stuck to that part of sed, where I thought that how can I extract text from sed, where you can replace text using sed.
I mean I was trying to do this in sed:

sed -n 's/[[:digit:]]/WhatToPutHere/2p'
Knowing that the second digit is the episode number.

I would have used 3p where the episode number entered double digits.