processing multiple extensions

6,965

Solution 1

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.

Solution 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.

Share:
6,965

Related videos on Youtube

Pol Hallen
Author by

Pol Hallen

Updated on September 18, 2022

Comments

  • Pol Hallen
    Pol Hallen almost 2 years

    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)

    • Celada
      Celada almost 10 years
      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!
  • Pol Hallen
    Pol Hallen almost 10 years
    thanks for help. I've added your suggestion but the script process only jpg files... strange...
  • cuonglm
    cuonglm almost 10 years
    Are you sure all your file is in the same folder? What is your bash version?
  • Pol Hallen
    Pol Hallen almost 10 years
    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
  • mikeserv
    mikeserv almost 10 years
    @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.
  • cuonglm
    cuonglm almost 10 years
    @mikeserv: I am waiting for OP to confirm the brace expansion work or not, I then think about solution like yours, because it may be more difficult for OP to understand it than brace expansion only.
  • Pol Hallen
    Pol Hallen almost 10 years
    Sorry for mistake :-( I had /bin/myscript indeed the new script had to /home/user/bin/myscript. Thanks for help!
  • mikeserv
    mikeserv almost 10 years
    Hooray! That's good to know - I thought the brace expansion was by default not interpreted unless at a prompt even with a #!/bin/bash bang. Thanks, Gnouc.
  • bluenote10
    bluenote10 about 4 years
    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?
  • Joseph Larson
    Joseph Larson almost 3 years
    Note that it won't work if there are spaces. echo foo.{a,b,c} will work echo foo.{a, b, c} will not. (note spaces after commas).
  • Stéphane Chazelas
    Stéphane Chazelas almost 3 years
    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).
  • Valdemar_Rudolfovich
    Valdemar_Rudolfovich almost 3 years
    @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
  • Stéphane Chazelas
    Stéphane Chazelas almost 3 years
    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.