List multiple file types in bash for loop

bashbash-scripting

I wrote a script that converts images in a folder. The script uses a for loop:

i="1"
for file in *.jpg; do
     outputFile=$(echo "image"$(echo $i))
     convert "$file" -resize 50x50 $outputFile
     i=$[i+1]
done

What I want to do is allow the script to run on multiple file type extensions. Now I've tried doing:

for file in *.jpg *.JPG *.jpeg; do
....
done

The problem I have with this is that if you are in a folder with all *.JPG and no *.jpg, the script still bumps i+1 even though there was no images, because it runs the for loop anyways, upon not finding any *.jpg it goes onto *.JPG.

How can I target multiple file extensions without it running itself per type? Example, is their syntax something like this:

for file in [*.jpg | *.JPG]; do
...

?
That way my output folder always contains images labeled like this:
image1.jpg
image2.jpg
image3.jpg
etc..

Instead of ending up with a folder missing image1.jpg because it had no *.jpg to run on first.

Best Answer

The Solution

Use nullglob. Put the following line before the for loop:

shopt -s nullglob

nullglob means that if there is no such file, the glob is removed from the list. Observe without nullglob:

$ echo  *.jpg *.JPG *.jpeg
test.jpg *.JPG *.jpeg

Now, with nullglob:

$ shopt -s nullglob
$ echo  *.jpg *.JPG *.jpeg
test.jpg

Revised Script

The complete script could be:

i=1
shopt -s nullglob
for file in *.jpg *.JPG *.jpeg; do
     convert "$file" -resize 50x50 "image$i.jpg"
     i=$((i+1))
done

Three notes:

  1. In the definition of outputFile, all those echo statements were unnecessary.

  2. Following convention, I added an extension, .jpg, to your output file name. If you really don't want the extension, just remove it.

  3. I replace $[...] with its more standard form: $((...)).

Related Question