Script to rename files by moving a part of the filename to the beginning of the file’s name

I frequently need to rename files by moving a string that's part of the existing file's name to the beginning of the filename. Here's a script that will take a string as an argument and rename files by moving the string to the start of the file name.

For example, let's say have I two files with string "word" in them:

ak@lark:~$ ls -1
bar.word.baz
foo.word.bar

Let's say I want to move the string "word" to the beginning of each file's name. I would first run the script with "-s" flag to simulate what would be done without messing things up:

ak@lark:~$ string2front -s word
would rename: foo.word.bar > wordfoo..bar
would rename: bar.word.baz > wordbar..baz

Ok, good, but this is not exactly what I want, I want the period moved as well:

ak@lark:~$ string2front -s word.
would rename: foo.word.bar > word.foo.bar
would rename: bar.word.baz > word.bar.baz

Now that I'm happy with the proposed outcome, I run the script without the "-s" flag:

ak@lark:~$ string2front word.
renaming foo.word.bar > word.foo.bar
renaming bar.word.baz > word.bar.baz

The result:

ak@lark:~$ ls -1
word.bar.baz
word.foo.bar

UPDATE 2011-12-29: The same (or nearly so), could also be accomplished with the rename utility included in Debian and friends. To move a string like in the examples above, could do:

string="word."
rename "s/$string//" *
rename "s/^/$string/" *

There are minor advantages to using the script below for this narrow use case, but on balance, it probably wasn't worth the effort..

On that depressing note, here's the script:

#!/bin/bash
 
if [ -z "$1" ]; then
  echo "Error: please provide a string. See --help for usage."
  exit 1
fi
 
usage() 
{
 echo "Usage: $0 [-s] string"
 echo " "
 echo "Script to move a string that's part of the file name to the"
 echo "beginning of the file name. Will ignore files whose names"
 echo "already start with the string. Will not overwrite existing files"
 echo "unless explicitly directed to do so."
 echo ""
 echo "Options:"
 echo "    -s, --simulate     Show what would be done without doing it."
 echo "    -f, --force        Overwrite existing files."
 echo "    -h, --help         This help message."
 echo ""
}
 
case "$1" in
  -s|--simulate)
     shift
     simulate="yes"
     string="$1"
     ;;
  -f|--force)
     shift
     force="yes"
     string="$1"
     ;;
  -h|--help)
     usage
     exit 0
     ;;
  *)
     string="$1"
     ;;
esac
shift
 
files=$(find . -maxdepth 1 -name "*$string*" | sed "s|./||;/^$string/d;")
 
if [ -z "$(echo "$files" | sed "/^$/d")" ]; then
  echo "No files to process"
else
  echo "$files" | sed "/^$/d" | while read f
  do
    nf=$(echo $f | sed "s/$string//;s/^/$string/;")
    if [ $simulate ]; then
      echo "would rename: $f > $nf"
    else
      if [ -e "$nf" ]; then
        if [ $force ]; then
          mv "$f" "$nf" && echo "renamed $f > $nf (overwrote existing)"
        else
          echo "INFO: target file '$nf' exists, supply '-f' option to overwrite."
        fi
      else
        mv "$f" "$nf" && echo "renamed $f > $nf"
      fi
    fi
  done
fi

Leave a comment

NOTE: Enclose quotes in <blockquote></blockquote>. Enclose code in <pre lang="LANG"></pre> (where LANG is one of these).