Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I've a problem modifying the files' names in my Music/ directory.

I have a list of names like these:

$ ls
01 American Idiot.mp3
01 Articolo 31 - Domani Smetto.mp3
01 Bohemian rapsody.mp3
01 Eye of the Tiger.mp3
04 Halo.mp3
04 Indietro.mp3
04 You Can't Hurry Love.mp3
05 Beautiful girls.mp3
16 Apologize.mp3
16 Christmas Is All Around.mp3
Adam's song.mp3
A far l'amore comincia tu.mp3
All By My Self.MP3
Always.mp3
Angel.mp3

And similar and I would like to cut all the numbers in front of the filenames (not the 3 in the extension).

I've tried first to grep only the files with the number with find -exec or xargs but even at this first step I had no success. After being able to grep I'd like doing the actual name change.

This is what I tried by now:

ls > try-expression
grep -E '^[0-9]+' try-expression

and with the above I got the right result. Then I tried the next step:

ls | xargs -0 grep -E '^[0-9]+'
ls | xargs -d '\n' grep -E '^[0-9]+'
find . -name '[0-9]+' -exec grep -E '^[0-9]+' {} \;
ls | parallel bash -c "grep -E '^[0-9]+'" - {}

And similar but I got error like 'File name too long' or no output at all. I guess the problem is the way I'm using xargs or find as expressions in separate commands work well.

Thank you for your help

share|improve this question

4 Answers 4

up vote 5 down vote accepted

To list all files start with number in a directory,

find . -maxdepth 1 -regextype "posix-egrep" -regex '.*/[0-9]+.*\.mp3' -type f

Problem with your approach is that the find returns a relative path of a file and you are just expecting a filename itself.

share|improve this answer
    
Thank you for your help! –  Luigi Tiburzi May 29 '12 at 10:55

Here's something you could do using only bash, with a regex in a conditional:

#! /bin/bash

# get all files that start with a number
for file in [0-9]* ; do
    # only process start start with a number
    # followed by one or more space characters
    if [[ $file =~ ^[0-9]+[[:blank:]]+(.+) ]] ; then
        # display original file name
        echo "< $file"
        # grab the rest of the filename from
        # the regex capture group
        newname="${BASH_REMATCH[1]}"
        echo "> $newname"
        # uncomment to move
        # mv "$file" "$newname"
    fi
done

When run on your sample file names, the output is:

< 01 American Idiot.mp3
> American Idiot.mp3
< 01 Articolo 31 - Domani Smetto.mp3
> Articolo 31 - Domani Smetto.mp3
< 01 Bohemian rapsody.mp3
> Bohemian rapsody.mp3
< 01 Eye of the Tiger.mp3
> Eye of the Tiger.mp3
< 04 Halo.mp3
> Halo.mp3
< 04 Indietro.mp3
> Indietro.mp3
< 04 You Can't Hurry Love.mp3
> You Can't Hurry Love.mp3
< 05 Beautiful girls.mp3
> Beautiful girls.mp3
< 16 Apologize.mp3
> Apologize.mp3
< 16 Christmas Is All Around.mp3
> Christmas Is All Around.mp3
share|improve this answer
    
While already using a regular expression, you not need to remove the unwanted characters with parameter expansion. Change the if condition to [[ $file =~ ^[0-9]+[[:blank:]](.+) ]] and you will have the new name in newname="${BASH_REMATCH[1]}". –  manatwork May 29 '12 at 9:50
    
Good point, and what's more, my script was a bit buggy if a file starts with numbers followed with more than one space. (Would be renamed to a filename that starts with spaces, which is really a pain...) Fixed up with your suggestion. –  Mat May 29 '12 at 9:58

On Debian, Ubuntu and derivatives, use the rename perl script.

To simulate the rename operation:

    rename 's/^\d+ //' * -n

Remove the -n (no act) to perform the operation:

    rename 's/^\d+ //' *

With a little luck perl rename is installed as /usr/bin/rename on your distribution, too (Rumour has it that Fedora also uses perl rename).

See the perl rename man page for more details on other features.

share|improve this answer
    
Work perfectly, thank you! –  Luigi Tiburzi May 29 '12 at 10:57

It's relatively easy in zsh with zmv:

zmv '[0-9]## #(*.mp3)' '$1'

Explanation: [0-9]## # is a pattern that matches one or more digits followed by zero or more spaces. The command above renames all files that begin with this pattern and end with .mp3 to the part caught by the parentheses.

share|improve this answer

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.