Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I am modifying a simple BASH script to remove numbers and hyphens from the start of my MP3 files. The aim is to rename files such as:

  • 11 Song 1.mp3
  • 1-1-Song 2.mp3
  • 11-1 Song 3.mp3

to:

  • Song 1.mp3
  • Song 2.mp3
  • Song 3.mp3

I have this script which works for all the files in the current directory

$ for f in [0-9]*; do mv "$f" "`echo $f | sed 's/^[0-9]*\W*//'`"; done

and have modified it to look for all files inside subfolders:

#!/bin/bash

dir=''

IFS='
'
for f in $(find $dir * -type f) ; do
  mv "$f" "`echo $f | sed 's/^[0-9]*\W*//'`"; 
done

The problem is that the $f value returns the subfolder and the filename and the mv line looks for files beginning with [0-9], therefore any files within a subfolder are not being renamed.

E.g. The file mp3/1-1 Song 1.mp3 begins mp3/, does not start with a numeric so it's not renamed.

Is there a way I can read the directory and file values into separate variables or is there a better way of doing this?

Thanks

share|improve this question
    
+1.nice question –  user61928 Oct 16 '12 at 12:37
add comment

3 Answers

up vote 3 down vote accepted

find & sed: I would ask you to first remove the pipe and sh at the end, and see whether the mv command is getting generated properly, and then you can run the command as such:

find $dir -type f | sed 's|\(.*/\)[^A-Z]*\([A-Z].*\)|mv \"&\" \"\1\2\"|' | sh
share|improve this answer
    
Nice solution! Note that this slightly changes the question in that it removes everything before the first upper case character in the filename (instead of just digits and hyphens). If that is desirable, you probably at least want to change both A-Z instances to A-Za-z in case any titles don't contain upper case characters. –  glibdud Oct 16 '12 at 13:01
    
Agree very nice solution - thanks for posting. –  Stephen Provis Oct 16 '12 at 16:44
add comment

Theres no need for a script, there's a one liner for that.

Try this to see what it does (don't worry, this doesn't rename your files yet, see below):

find root_audio_path -type f -iname '*mp3' -execdir rename --no-act 's/^\.\/[\d\s\-]+/\.\//' '{}' ';'

Remove --no-act if it seems to work. This actually renames the files.

The -execdir option of find makes sure that rename is executed in the files directory, so the files paths always start with ./ - for which we look for in rename.

rename in Ubuntu actually perls rename, so you can use regular expressions there.

share|improve this answer
    
This seems to work but does not move beyond the parent folder, which is where the problem comes in. –  Stephen Provis Oct 16 '12 at 16:40
    
It works for any number of sub folders as well. The output you see is the one of rename, which is run in every directory. Because it's working directory is always ./, that's all you see. However, the files get renamed in all subdirs. –  phoibos Oct 16 '12 at 17:25
add comment

The following will get you the path

echo "wwww/www/mp3/1-1 Song 1.mp3" | sed 's#\(.*/\)\(.*\)#\1#g'
/wwww/www/mp3/

The following will get you the file without the path:

echo "wwww/www/mp3/1-1 Song 1.mp3" | sed 's#\(.*/\)##g'
1-1 Song 1.mp3

You will need a variable for the path, old and new filenames. You can get the new filename using your code and build a source and target path using these variables. I'd recommend doing a dry-run where you echo the target appending to a file. Then you can check for d

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.