Need some scripting pointers

Hi All,
I’ve got some audio books that I’ve ripped to my file system as MP3’s.
All the file names were written with spaces (ex. Track 1.mp3)

I want to batch move them to to file names without the space sort of like
for filename in ls;
do
mv $filename filename_no_spaces
done

I know this is an extremely simplistic representation of a more complicated bit of scripting… or maybe it’s simpler than I think…

I found that “filename in” grabs each set of characters and separates them at the “space” character so that I get back “Track” and “1.mp3” as separate values.

I also want to add a zero before numeric characters [1-9] but not before [11-xx]

So “Track 1.mp3” becomes “Track_01.mp3” but “Track 10.mp3” becomes “Track_10.mp3”

I’ve not been doing any scripting for the last few years and I’ve forgotten just about everything. Any help greatly appreciated.

Thanks
Greyangel

You can use the new bash matching facilities.

First of all you have to forget about ls. That will break arguments at spaces. If you want the contents of the whole directory, try this:

for f in *

or perhaps

for f in *.mp3

Then inside the loop you have to refer to “$f”.

To change the spaces to _s, do this:

mv "$f" "${f// /_}"

To add 0 to single digit names, try this second pass:

for f in Track_[0-9].mp3
do
  mv "$f" "${f/Track_/Track_0}"
done

Cool! Kind of like inline sed’ding without sed and automatic ls?

Works like a champ! Thanks a bunch!

Greyangel

On Mon, 31 Jan 2011 01:36:01 +0000, greyangel wrote:

> mv $filename filename_no_spaces

rename " " “_” *.mp3

That’ll take care of the spaces in all the files, assuming they’re the
only files in the directory.

There’s probably a similarly easy way to do the addition of a 0 to tracks
1-9, the suggestion Ken made would work as well as anything. :slight_smile:

Jim


Jim Henderson
openSUSE Forums Administrator
Forum Use Terms & Conditions at http://tinyurl.com/openSUSE-T-C

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Good suggestions; I always learn something fun from your input.

I would, personally, have used the rename command for both of these (note
the need to run rename multiple times in the examples below if there are
MULTIPLE spaces in the names):

rename ’ ’ ‘_’ *.mp3

The rename command’s manpage actually includes an example for adding
leading-zeros to numbers.

Good luck.

On 01/30/2011 07:06 PM, ken yap wrote:
>
> You can use the new bash matching facilities.
>
> First of all you have to forget about ls. That will break arguments
> at spaces. If you want the contents of the whole directory, try this:
>
>
> Code:
> --------------------
> for f in *
> --------------------
>
>
> or perhaps
>
>
> Code:
> --------------------
> for f in *.mp3
> --------------------
>
>
> Then inside the loop you have to refer to “$f”.
>
> To change the spaces to s, do this:
>
>
> Code:
> --------------------
> mv “$f” "${f// /
}"
> --------------------
>
>
> To add 0 to single digit names, try this second pass:
>
>
> Code:
> --------------------
> for f in Track_[0-9].mp3
> do
> mv “$f” “${f/Track_/Track_0}”
> done
> --------------------
>
>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.15 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJNRhzyAAoJEF+XTK08PnB5Bu0P/0YH/FDw0XO3ZDM3WDMXRlIt
aze5NO6ne2Us2vXszWWkcGdZ8FQzMxrF3hABPUIGFoFV658NiB6ltJUG6tLQBZO6
VZsYWankFlSL7avi1IViPyPCUa8Wv0cErCCBP//BW5Hxgb3FKDZqCtVYK6dB/dlT
T/WN0Fu5e3yfadQHK/no1s70FwElgZDhwE2G1a1tLUJpAmK17ip8eOje24gMbddv
P2pVYJaIOHYCek2Lks4Zajv/u+/syXmlA4rZZ7o4G0DvGaZvFi8H6w3X6KT8zogO
kL97U7yTCiPD6OqtqfU84bzEPE/rWtPwLugL47S2kcjA89GCLgZ3eq3+1/4T8Ykj
A9jf2k82oz7FzXYqgZsFU59dk0oI6up65WwLWi1PNEX3xbHwJQKzkM+Sblk5naC6
np4E9DKVpMwBYJ8sOJO4hz+AI8zOBe3PncAD2T647LHnXW2SwRoivsfzpVISzvbq
HWlwzgwJz0dZ5622ErtD3rydC51rosVsGTYXJqxWX5KjAYBLihns0cYjq5wRyQ+J
IPXRWeOosTHFajDhtflpYIxk6v6Boym7OzhFVreJQbqdwxKnYijr2/ac32noREyI
37yhLgO4ZX/6AHQt/423A5bXD3toSfxIYiE9/bBs3llQxgmVqXnnHXwvYI3BroUu
bAfy1Uuf0l4e9LJpHret
=Yjl4
-----END PGP SIGNATURE-----

Errm, I might not know enough to be giving advice here since batch renames are something of a black art and I’m not sure what I would do, but I am pretty sure you can just use the “rename” command. See “man 1 rename”. Basically I think the rather cryptic and somewhat dangerous looking

rename \  _ *.mp3

will replace the space in each filename with an underscore. Note that’s two spaces after the \ character, i.e. an escaped space, followed by a normal space to separate the from and to arguments of the rename command. Oh wait quoting works too, it seems:

rename " " _ *.mp3

As to adding the zero, there I’m not so sure, maybe something like

rename Track_ Track_0 Track_?.mp3

after you’ve already done the above command, since the filenames with double digits won’t be included in the list of files brought in by Track_?.mp3. As I said I’m no expert, and batch renaming seems like a good way to bugger up a lot of stuff at once, so maybe be careful and take what I’m saying with a grain of salt. Oh and I guess my answer isn’t really a script but I guess you could put the two commands in a row in a script file :wink:

Edit: Oh wait Jim Henderson beat me to it but I’ll leave this and just add that I think it only replaces the first occurance in each filename, so if there were two spaces per filename then you might have to run it twice.

So that is a rename function rather than a shell function? I started to “set -o vi” and then thought better of it…

Cool stuff.

Since rename is actually a Perl script, you could also write a custom Perl script and feed the filenames into it. Then you can do really cool things with regexes if the requirements get complex:

#!/usr/bin/perl -w
while (<>) {
        chomp($_);
        ($n = $_) =~ s/ /_/g;
        ($n2 = $n) =~ s/(\D)(\d\.mp3)/${1}0$2/;
        $n = $n2 if ($n2 ne $n);
        rename($_, $n);
}

You would do this:

ls *.mp3 | ./fixnames.pl

On Mon, 31 Jan 2011 03:36:01 +0000, ken yap wrote:

> Since rename is actually a Perl script

Not on my system, it’s in /usr/bin and is an ELF executable. :slight_smile:

Jim


Jim Henderson
openSUSE Forums Administrator
Forum Use Terms & Conditions at http://tinyurl.com/openSUSE-T-C

Ah, ok I was looking at a Debian system.