14

I have done a script to convert recursive .jpg files to another size:

echo $re
mkdir "$re"_tmp
for a in *.jpg ; do convert "$a" -resize $re "$re""_tmp/${a%.*} ["$re"].jpg" ; done

I'd like integrate a multi extension support: png, bmp, etc. better with:

FILEFORMAT="jpg, JPG, png, PNG, bmp, BMP"

any idea to build it?

PS: variable re is the new size 1024x768 (or 800x600, etc)

1
  • 1
    I hope you would consider processing files matching *.jpeg as well. Apparently someone in the distant past thought it should be *.jpg and this misnomer caught on in a big way... but it seems quite wrong: as if the Joint Photographic Experts Group became the Joint Photographic Group, the implication being that they're not experts!
    – Celada
    Jul 28, 2014 at 0:48

3 Answers 3

25

If I understand right, you want to process files with other extension, instead of only jpg. So you can try:

for a in *.{jpg,JPG,png,PNG,bmp,BMP}; do
  printf '%s\n' "$a"
  # do your stuff here
done

{...} is bash feature called brace expansion.

10
  • thanks for help. I've added your suggestion but the script process only jpg files... strange...
    – Pol Hallen
    Jul 26, 2014 at 17:38
  • Are you sure all your file is in the same folder? What is your bash version?
    – cuonglm
    Jul 26, 2014 at 17:41
  • Hi, version of bash is 4.3-7 (debian testing) and yes, the files are on same folder. I know that the script rename all files to jpg but this is not a problem. Thanks
    – Pol Hallen
    Jul 26, 2014 at 17:44
  • 2
    @Gnouc - are you certain this is not just an interactive shell thing? Also, even if not, it will very likely not work if the #! is for sh. It would be much simpler to do: set -- *.[jJ][pP][gG] *.[bB][mM][pP] *.[pP][nN][gG]; for pic do...;done which would keep the file list in "$@" for multiple process loops as necessary.
    – mikeserv
    Jul 26, 2014 at 17:58
  • 1
    This approach doesn't seem to work for me: If a certain extension does not match (say no *.JPG file) the for loop variable a takes the value of the pattern itself e.g. *.JPG. The matching cases are returned properly. Is there a way suppress returning the non-matching patterns?
    – bluenote10
    Jun 20, 2020 at 14:53
2

You may use multiple GLOB expressions separated by space:

for a in *.[jJ][pP][gG] \
         *.[jJ][pP][eE][gG] \
         *.[pP][nN][gG] \
         *.[bB][mM][pP]
do
    echo "$a" "$re/$a"
done

# or inline
for a in *.[jJ][pP][gG] *.[jJ][pP][eE][gG] *.[pP][nN][gG] *.[bB][mM][pP] ; do echo "$a" "$re/$a"; done

Not sure if it is POSIX compatible, but I believe it is.

3
  • 1
    The only thing not POSIX in there would be the usage of echo which is unspecified for arguments containing arbitrary sequences of bytes such as filenames. See also Why is printf better than echo?. Another potential problem is that in POSIX compliant shells (and that is a misfeature from the Bourne shell specified by POSIX), the *.[jJ][pP][gG] expands to *.[jJ][pP][gG] if there's no matching file (so you could end up processing a file by that name). Jul 26, 2021 at 18:14
  • @StéphaneChazelas, thank you for the explanation, seems to use GLOB is not a good idea. I wonder if using find util is better? For example: for f in $(find . -maxdepth 1 -type f \( -iname '*.bmp' -or -iname '*.png' -or -iname '*.jpeg' -or -iname '*.jpg' \) ) ; do printf "%s\n" "$f" ; done Jul 26, 2021 at 23:35
  • 3
    Note that -iname is not POSIX. See also Why is looping over find's output bad practice?. In your glob loop, you can always filter out non-matches or non-regular files with an extra [ -f "$a" ] || continue. Jul 27, 2021 at 5:23
0

Here is a POSIX complaint variant:

for a in *.jp* *.JP*; do
  [ -f "$a" ] || continue
  echo "Processing $a"
done
  1. In POSIX you may put multiple GLOBs separated by space
  2. In real life extensions are ether in lower case jpg or in upper JPG but not with mixed case.
  3. If no any JPG files then the glob wont be expanded and the var a will have *.JP* value. You must filter out it by checking that hte file is exists with the [ -f "$a" ]
1
  • 1
    This wrongly matches files like foo.jp and bar.jpbaz.
    – basteln
    Sep 22, 2022 at 6:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .