I'm using the following simple line of code successfully to remove a specified word from all file names in a directory:

for file in *.* ; do mv "${file}" "${file//UNWANTEDWORD}"; done

But what can I add to that code to specify only subdirectories in a directory and NOT files?

So to restate: I want to remove a specific word from every subdirectory name inside a directory which contains both directories and files, and have it not effect the files. Any ideas?


Note: this assumes that your original glob expression *.* is correct, i.e. that you wish to loop over directories whose names contain a period character, like foo.bar

You can make the shell glob *.* match only directories by suffixing it with /:

for file in *.*/ ; do mv "${file}" "${file//UNWANTEDWORD}"; done

Alternatively, add a simple directory test:

for file in *.* ; do [ -d "$file" ] && mv "${file}" "${file//UNWANTEDWORD}"; done
  • Thanks steeldriver, your first answer was the simple answer I was hoping for, unfortunately when I tried it, I got error: "mv: cannot stat '*.*/': No such file or directory" :( – ExisDeni Jul 27 '20 at 22:17
  • 2
    @ExisDeni do you actually have directories that have periods in their names? – steeldriver Jul 27 '20 at 22:23
  • The second option doesn't work either :( There is no error but none of the directory names change, just nothing happens. – ExisDeni Jul 27 '20 at 22:23
  • steeldriver: uh...no i don't, oops. Thanks, I got it now: */ – ExisDeni Jul 29 '20 at 22:27


find ./dir1 -depth -type d -name '*UNWANTEDWORD*' -exec bash -c 'mv "${1}" "${1//UNWANTEDWORD}"' mv {} \;

The above searches recursively through the directory structure. If you want to operate only files in the current directory, ., then run:

find ./dir1 -maxdepth 1 -depth -type d -name '*UNWANTEDWORD*' -exec bash -c 'mv "${1}" "${1//UNWANTEDWORD}"' mv {} \;

How it works

  • find ./dir1

    Start a find command and tell it which directory to look in. If you want to start with the current directory, replace ./dir1 with ..

  • -depth

    Search each directory's contents before the directory itself.

  • -type d

    Search only for directories.

  • -name '*UNWANTEDWORD*'

    Limit the search to directory names containing UNWANTEDWORD. There is no point wasting time on directories that don't have this word.

  • -exec bash -c 'mv "${1}" "${1//UNWANTEDWORD}"' move {} \;

    Run your shell command on each file found.

    (In the above, when the shell command is executed, the string move is assigned to $0. This is unimportant unless the shell code generates and error in which case the error message use $0 as the script name.)

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.