I was reorganizing my music library and decided to change the naming convention I’ve used. This task is just asking to be automated. Since the filename change could be described using regular expression, I looked for a way to use sed
for the renaming process.
The files I had, had the following pattern as filename ARTIST – SONG – TRACK – ALBUM
James Brown - I Got You (I Feel Good).ogg - 01 - Classic James Brown
I wanted to rename it to ARTIST – ALBUM – TRACK – NAME
James Brown - Classic James Brown - 01 - I Got You (I Feel Good).ogg
Describing the change as a sed
program is easy:
s/\(.*\) - \(.*\) - \(.*\) - \(.*\).ogg/\1 - \4 - \3 - \2.ogg/
Now all that has to be done is to pass each filename to mv and pass it again after it went through the sed
script. This could be done like this:
for i in *; do
mv "$i" "`echo $i | sed "s/\(.*\) - \(.*\) - \(.*\) - \(.*\).ogg/\1 - \4 - \3 - \2.ogg/"`";
done
The important part is the
`echo $i | sed "s/\(.*\) - \(.*\) - \(.*\) - \(.*\).ogg/\1 - \4 - \3 - \2.ogg/"`
which pipes the filename to sed
and returns it as an argument for mv
.
To see what renaming will be done one can alter a bit the above command, and get
for i in *; do
echo "$i" "->" "`echo $i | sed "s/\(.*\) - \(.*\) - \(.*\) - \(.*\).ogg/\1 - \4 - \3 - \2.ogg/"`";
done
While will effectively print a list of lines of the form oldname -> newname
.
Of course this technique isn’t limited to the renaming I’ve done. By changing the pattern given to sed
, one can do any kind of renaming that can be described as a regular expression replacement. Also one can change the globbing (the *) in the for loop to operate only on specific files, that match a given pattern, in the directory instead of all of them.
Thanks Guy for the inspiration this page gave me.
I had no experience of sed or awk but quickly got a sed solution to almost solve my problem and then discovered that arithmetic is not easy with sed.
After much playing the following worked:
This changes the names of all files below /test which start with ‘ts’. My file names were 137 characters long and included many special characters. They ended with comma separated data which I wanted to retain and decrease by 1000. My solution separates the data with a hyphen and adds an extension. Whilst restricting ‘find’ to files starting with ‘ts’ is not necessary it ensures directory names are not included (unless they start with ts!) and prevents the modified names being modified again – these may not happen but I think this simple restriction is a wise precaution.
oops – for “increase” read ‘decrease’.
Guy – perhaps you could edit this for me and format the code.
Done, I’m glad it has been an inspiration. I’m aware of awk’s advantages over sed, but I just didn’t find the time, yet, to learn it properly. Sed is much simpler.
Hello Guy,
it seems the you have quite some batch file programming experience! 🙂
Is it possible to replace “” with ” using sed?
(double quote replaced with single qoute)
I like to turn “”path”” to “path”.
Or do you know a side with a documentation for sed?
Have you tried
sed s/\"\"/\"/
?
Hello Guy, thank you for you answer.
No I haven’t. I larked around with “FOR /F” until I read about sed on the web. Then you found your blog.
But I am not sure anymore, if sed is helping me further, since I am on Windows…
I understood, that sed is a Unix specific command. Is this correct? Do you know of an equivalent on Windows?
Thanks again!
sed
is indeed a unix command, so it doesn’t exist natively in Windows. You can always intall something like cygwin which gives you a unix environment inside your windows. Also I’m pretty sure that searching for “sed for windows” would turn up useful results.Coming back to the issue, I’m feeling python is more suitable. A bit longer but safer (no shell escaping problems).
The example above separates year-month dates using a dash (201201 -> 2012-01).
Great article, which does nearly what I want. I’m trying the 2nd echo version rather than rename (mv) version. The displayed output is always i$, so it doesn’t seem to pipe into sed correctly. I’m relatively new to linux and sed and struggling to understand the various quotes and double quotes used, so not sure what’s going wrong.
Thanks for the article, it really helped me!
May I suggest a typo correction?
For consistency and to avoid confusion, the asterisked words should be uniform and share the same nomenclature. Perhaps both should say “SONG” rather than “NAME”.