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.
Related videos on Youtube
![Pol Hallen](https://i.stack.imgur.com/Xpew4.jpg?s=256&g=1)
Author by
Pol Hallen
Updated on September 18, 2022Comments
-
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 almost 10 yearsI 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 almost 10 yearsthanks for help. I've added your suggestion but the script process only jpg files... strange...
-
cuonglm almost 10 yearsAre you sure all your file is in the same folder? What is your bash version?
-
Pol Hallen almost 10 yearsHi, 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 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 forsh
. 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 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 almost 10 yearsSorry for mistake :-( I had /bin/myscript indeed the new script had to /home/user/bin/myscript. Thanks for help!
-
mikeserv almost 10 yearsHooray! 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 about 4 yearsThis approach doesn't seem to work for me: If a certain extension does not match (say no
*.JPG
file) the for loop variablea
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 almost 3 yearsNote 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 almost 3 yearsThe 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 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 almost 3 yearsNote 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
.