Today I’m sharing a small bash script that I needed some days ago to edit a bunch of files.

Let’s say you were doing a security copy of your favourite CD album a while ago and you were doing it with a trial version of some CD Ripper software which created an output that looked like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-10-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-11-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-12-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-13-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-14-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-15-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-1-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-2-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-3-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-4-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-5-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-6-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-7-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-8-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 bestcdripperever.com_Artist-Album-9-Title.mp3

Pretty long and unnecessary name for a file right? But with a mighty tool like /bin/bash this is no challenge for us.

Here is how to change the files with a command that fits into one line. Here it goes:

1
for i in $(ls); do for j in $(echo $i |awk -F_ '{ print $2 }');do mv -v $i $j; done; done

et voilà, the folder now looks much more tidy:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-10-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-11-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-12-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-13-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-14-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-15-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-1-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-2-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-3-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-4-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-5-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-6-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-7-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-8-Title.mp3
-rw-r--r-- 1 simon simon 0 Jun  9 20:30 Artist-Album-9-Title.mp3

So what is the magic behind this?

Let’s look at all the commands that were used:

  • for : a simple for-loop look like this: ‘for i in 1 2 3; do some_command; done’ (note that we are using two in this one-liner)

  • ls : shows the content of the directory without any information about the contents

  • echo : writes something on the standard output (so that we see it on the commandline)

  • awk : a neat command that can manipulate input, the parameter -F followed by a character divides the input into pieces, which you can then output using { print $columnnumber }

  • mv : moves files, can also be used for renaming

So, the first for-loop is running through all the files in the directory and creates variables ($1,$2,$3,etc.). The second for-loop prints the file of every line the first for-loop has gathered and divides the part before and after the _ . It only remembers the part after it, though ($2). Now we have the old file name in $i and the new name without our prefix in $j. Now the second for-loop just renames every single file in the directory.

That’s it!