1

I want to rename multiple files using the command-line, removing a pattern from the filename while retaining the rest.

Original output:

$ ls
Versailles - Holy Grail (2011)
Versailles - Jubilee (2010)
Versailles - Noble (2008)

Desired output after command:

$ ls
Holy Grail (2011)
Jubilee (2010)
Noble (2008)

1 Answer 1

3

Bash

With pure Bash, removing everything up to the first -:

for f in *; do mv -- "$f" "${f#*- }"; done

If you want to remove everything up to the last -, use ## instead of #.

To break it down:

  • The for iterates over every file in the current directory (*), and calls mv on each file found.
  • The -- tells mv to stop parsing options and is a safeguard to prevent files starting with - from being interpreted as options (e.g. a file called -i would cause mv to prompt you before moving).
  • The ${f#*- } is string manipulation and removes the part you don't want from each filename.
  • All variables are quoted to prevent filenames with spaces or globbing characters to break the command. Always double-quote your variables.

rename

With rename that's commonly found in Linux distributions, e.g. if you want to specify the artist:

rename 's/Versailles - //' *

Or if you want to remove everything up to the last -:

rename 's/.*- //' *

Zsh

In Zsh and zmv, which you need to load with autoload -U zmv:

zmv 'Versailles - (*)' '$1'
2
  • Thanks! I use Zsh and have rename installed, but I want to do this with bash. Could you break down the for-loop for me?
    – krystah
    Jan 10, 2014 at 9:58
  • Great in-depth answer. Thanks again :)
    – krystah
    Jan 10, 2014 at 10:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .