22

I'm trying to write a for loop in bash to get the files with extension of jpg, jpeg, png, this i my attempt, but does not work

for file in "${arg}"/*.{jpg,jpeg,png}; do echo ${arg}-something.jpg > z.txt ; done;

basically, i want to get the name of the file with those extension in the current folder, and do something with each file, then output the filename back with a new extension.

devric
  • 3,555
  • 4
  • 22
  • 36
  • 1
    Possible duplicate of [Matching files with various extensions using for loop](https://stackoverflow.com/q/6223817/608639), [for loop for multiple extension and do something with each file](https://stackoverflow.com/q/12259331/608639), [Loop over multiple file extensions from bash script](https://stackoverflow.com/q/49103942/608639), etc. – jww Aug 19 '18 at 06:44

2 Answers2

34

You are not using $file anywhere. Try

for file in "$arg"/*.{jpg,jpeg,png} ; do
    echo "$file" > z.txt
done
choroba
  • 231,213
  • 25
  • 204
  • 289
33

I would like to suggest 2 improvements to the proposed solution:

A. The for file in "$arg"/.{jpg,jpeg,png} will also produce "$arg"/.jpeg if there are no files with jpeg extention and that creates errors with scripts:

$ echo *.{jpg,jpeg,png}
myPhoto.jpg *.jpeg *.png

To avoid that, just before the for loop, set the nullglob to remove null globs from from the list:

$ shopt -s nullglob # Sets nullglob
$ echo *.{jpg,jpeg,png}
myPhoto.jpg
$ shopt -u nullglob # Unsets nullglob

B. If you also want to search *.png or *.PNG or *.PnG (i.e. ignore case), then you need to set the nocaseglob:

$ shopt -s nullglob # Sets nullglob
$ shopt -s nocaseglob # Sets nocaseglob
$ echo *.{jpg,jpeg,png}
myPhoto.jpg myPhoto.PnG
$ shopt -u nocaseglob # Unsets nocaseglob
$ shopt -u nullglob # Unsets nullglob
Nick De Greek
  • 1,834
  • 1
  • 18
  • 19