Renaming files with Bash, removing prefix and suffix

Óscar López picture Óscar López · Aug 20, 2012 · Viewed 12.3k times · Source

I want to rename a bunch of files using bash, transforming this file pattern:

prefix - name - suffix.txt

Into this one:

name.txt

For that I wrote the following script:

find . -name "*.txt" | while read f
do
  mv "${f}" "${f/prefix - /}"
done

find . -name "*.txt" | while read f
do
  mv "${f}" "${f/ - suffix/}"
done

It works, but I'd like to perform the renaming using a single loop. Is it possible?

Answer

chepner picture chepner · Aug 20, 2012

Another approach, for fun, using regular expressions:

regex='prefix - (.*) - suffix.txt'
for f in *.txt; do
    [[ $f =~ $regex ]] && mv "$f" "${BASH_REMATCH[1]}.txt"
done

Actually, using the simple pattern '*.txt' here has two problems:

  1. It's too broad; you may need to apply the regex to a lot of non-matching files.
  2. If there are a lot of files in the current directory, the command line could overflow.

Using find complicates the procedure, but is more correct:

find . -maxdepth 1 -regex 'prefix - .* - suffix.txt' -print0 | \
  while read -d '' -r; do
   [[ $REPLY =~ $regex ]] && mv "$REPLY" "${BASH_REMATCH[1]}.txt"
  done