1

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?

2 Answers 2

2

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
4
  • 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, 2020 at 22:17
  • 2
    @ExisDeni do you actually have directories that have periods in their names? Jul 27, 2020 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, 2020 at 22:23
  • steeldriver: uh...no i don't, oops. Thanks, I got it now: */
    – ExisDeni
    Jul 29, 2020 at 22:27
1

Try:

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.)

You must log in to answer this question.

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