Stuck With Using find and sed to Replace String in Filenames

findreplacesed

Following this post as a reference, I'm able to run a find and sed command without it throwing an error, but the filenames remain unchanged.

Trying to strip pronunciation_de_ from all mp3s in the current directory:

pronunciation_de_wählen.mp3
pronunciation_de_wange.mp3
pronunciation_de_weil.mp3
pronunciation_de_werden.mp3
pronunciation_de_zentrum.mp3

Before troubleshooting the command, here's a quick sanity check:
find . -name "*.mp3"
It returns all the mp3s in the current directory. Continuing on now that we know this part works…

sed --version returns sed (GNU sed) 4.4

I run find . -name "*.mp3" -exec sed -i 's/pronunciation_de_//g' {} \;

To make sure I'm fully understanding what's happening:

find . runs the find command in the current directory.
-name "*.mp3" returns any .mp3 filetypes.
-exec executes the next command you type.
sed -i The -i switch means work on the actual files, not a (temporary) copy.

For 's/old_word/new_word/g':

  • The s sets sed to substitute mode.
  • /old_word is the word you want to replace.
  • /new_word is the word you want to replace with. In my example it'll be blank.
  • /g apply the replacement to all matches (not just the first).

{} this string will be replaced by the filename during every iteration.
\; the semicolon terminates the find command. The backslash escapes the semicolon character in case the shell tries to interpret it literally.

Most of this information I'm getting from random blogs and Stack Exchange posts:

Understanding the -exec option of find
What is meaning of {} + in find's -exec command?

I really wanted to take my time and experiment and research before posting this almost-certainly-duplicate question but I'm completely stuck!

Best Answer

You can use find -exec ... to do the replacement in a one-line shell script.

find . -name "*.mp3" -type f -exec bash -c 'mv "$1" "${1/pronunciation_de_}"' bash {} \;

The filename {} is passed as parameter $1 to the executed bash process and ${1/pronunciation_de_} makes use of bash's parameter expansion capabilities and replaces the first occurrence of pronunciation_de_ in $1 with an empty string.

Additional option -type f makes sure to match only regular files.

Related Question