I've got a list of directories marked with "(Done)" at the end of the label.

For example: "Folder 1 (Done)"

I'm looking to remove "(Done)" from each directory using the rename command. Because it's a special character I'm using the escape character.

rename s/\(Done\)//g *

However, this command doesn't work. It removes the word "Done" and leaves the parentheses: "Folder 1 ()"


\ is a quoting operator in the shell syntax so:

rename s/\(Done\)//g *

Is the same as running:

rename 's/(Done)//g' *

And (, ) are special characters in the perl regular expression syntax (which rename uses) and need to be prefixed with \ (or changed to [(] and [)]) so they are treated literally.

So here, you want:

rename 's/\s*\(Done\)//g' ./*

Here also adding \s* to remove any whitespace before (Done), and a ./ prefix as some variants of rename would choke on file names that start with -.

  • First of all, thanks for your working solution. Struggling to get my head around the first explanation of how rename s/(Done)//g * = rename 's/(Done)//g' * – cworner1 Jun 15 '18 at 15:14
  • I've just quickly googled "Shell syntax backlash" and I can only find it's use as an escape character, not as a quoting operator. In this example the backlash is inbetween the first / and (Done) - yet the whole statement is surrounded by the single quote – cworner1 Jun 15 '18 at 15:17

This should work:

rename 's/\(.*\)|\[.*\]//g' *

Otherwise without using rename command (OT):

for file in folder*; do                                                          
    mv "$file" "${file/\(Done\)/}"

Using find:

find topdir -maxdepth 1 -type d -name '* (Done)' -exec sh -c '
    for pathname do
        mv "$pathname" "${pathname%" (Done)"}"
    done' sh {} +

This uses find to pick out the directories that have ␣(Done) at the end of their names and then uses a standard parameter substitution to remove that string.

No check is made to make sure there isn't already a directory/file with the target name in the same directory.

The sh -c script above could obviously be run by itself too, with minor modifications to do the tests that find did for it:

for pathname in topdir/*' (Done)'/; do
    mv "$pathname" "${pathname%' (Done)/'}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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