HOWTO Rename files using wildcards

HOWTO Rename files using wildcards

From Consultancy.EdVoncken.NET

Jump to: navigation, search

Say you have multiple files that need renaming, *.out to *.jpg for example.

People with a DOS background will probably type:

 ren *.out *.jpg

But this does not work in Unix shells due to the way commandline parameters are interpreted (in DOS, "ren" would do the wildcard expansion while in Unix, your shell expands the wildcards).

Contents

Renaming file extensions using the Bash shell

To achieve the same effect, we need to loop over the filenames and rename them one by one:

 for i in *.out; do
   mv "$i" "${i/.out}.jpg"
 done

Discussion

  • The "for i in <filespec>" loop runs the "mv" command for each matching filename
  • The "mv" command uses Bash variable substitution mechanism: "${i/.out}" contains the value of $i, without the ".out" extension. We then tack on the .jpg extension, and voila: all files are renamed.

So, if you just want to add an filename extension (say, .bak), the example becomes:

 for i in *; do
   mv "$i" "${i}.bak"
 done

More complex renaming

Say, I want to rename several files starting "fc9". The start of the filename should replaced with "fc10". Here, sed (stream editor) comes to the rescue:

 for i in fc9*; do
   n=`echo $i |sed s/fc9/fc10/`
   mv "$i" "$n"
 done

Discussion

  • Variable $i contains the current filename
  • The new filename, $n, is derived from $i using "regular expressions" available in sed.
  • In this example, we replace the first occurrence of the string "fc9" with "fc10". Here is another example to illustrate this behavior:
 $ touch aaabbbccc abcabcabc
 $ ls -l
 total 0
 -rw-r--r--  1 ed  staff  0 Feb  9 16:51 aaabbbccc
 -rw-r--r--  1 ed  staff  0 Feb  9 16:51 abcabcabc
 
 $ for i in a*; do n=`echo $i |sed s/a/b/`; mv $i $n; done
 $ ls -l
 total 0
 -rw-r--r--  1 ed  staff  0 Feb  9 16:51 baabbbccc
 -rw-r--r--  1 ed  staff  0 Feb  9 16:51 bbcabcabc
  • Should you wish to replace all occurrences of a string in the filename, use the "/g" modifier:
 $ touch aaabbbccc abcabcabc
 $ ls -l
 total 0
 -rw-r--r--  1 ed  staff  0 Feb  9 16:55 aaabbbccc
 -rw-r--r--  1 ed  staff  0 Feb  9 16:55 abcabcabc
 
 $ for i in a*; do n=`echo $i |sed s/a/b/g`; mv $i $n; done
 $ ls -l
 total 0
 -rw-r--r--  1 ed  staff  0 Feb  9 16:55 bbbbbbccc
 -rw-r--r--  1 ed  staff  0 Feb  9 16:55 bbcbbcbbc

See Also