Change the Extension on a Large Number of Files

Here’s a common problem. You untar an archive and it contains a large number of files that end .jpeg. You need them to have a .jpg extension. At first glance, you might be tempted to try this:
mv *.jpeg *.jpg

Give it a try and you will find it doesn’t work. The correct way to change the extension is to iterate over all of the files. Let’s start with the following:

[email protected]:/tmp/foobar$ ls
friday.jpeg  monday.jpeg  Saturday.jpeg  sunday.jpeg  Thursday.jpeg  Tuesday.jpeg  WEDNESDAY.jpeg
[email protected]:/tmp/foobar$

Once in the loop, you need to save the filename before the extension. I use a temporary variable and awk to extract it.

Here is my solution:

[email protected]:/tmp/foobar$ for i in *.jpeg
> do
>    basefilename=$(echo $i | awk -F.jpeg '{print $1}')
>    mv "$i" "$basefilename.jpg"
> done
[email protected]:/tmp/foobar$ ls
friday.jpg  monday.jpg  Saturday.jpg  sunday.jpg  Thursday.jpg  Tuesday.jpg  WEDNESDAY.jpg
[email protected]:/tmp/foobar$

I use double quotes around the variable names to compensate for filenames with spaces. In the awk statement I use the entire replacement pattern as my field separator. Using -F. will fail if you have a filename like

Logical AND and OR Using AWK

Before learning about AWK’s logical AND operator I used to string a pair of grep commands together to find two search terms:

grep abc filename | grep def

to find lines with both abc and def. This can be shortened into a single AWK command:

awk '/abc/&&/def/' filename

A logical OR is also provided using a pair of pipes ||

awk '/abc/||/def/' filename

You can also use the equivalent egrep command:

egrep 'abc|def' filename

To get comfortable with AWK, try using it instead of grep for a week. AWK has many more features than just printing fields from a file.