To check whether filename extensions of my images are correct, that is, whether my JPEGs are really JPEGs, PNGs are really PNGs, and WebPs are really WebPs, I can use the following ImageMagick command:
magick identify -format "%f: %m\n" *.(jp*|png|webp)
Or I can use "*.{jp*,png,webp}"
instead:
magick identify -format "%f: %m\n" "*.{jp*,png,webp}"
Note the quotation marks. Otherwise, if your target folder won't contain at least one file of each format, there will be an error.
magick identify -format "%f: %m\n" *.{jp*,png,webp}
zsh: no matches found: *.webp
ImageMagick itself supports both *.(foo|bar|barz)
and "*.{foo,bar,baz}"
syntaxes, but Zsh on my macOS, and I suppose Bash on Linux and BSD, supports only the first one, with parentheses ()
.
# works
file *.(jp*|png|webp)
# doesn't work at all. the {} syntax is not
# supported by Zsh and probably Bash
file *.{jp*,png,webp}
Hence my question. Which syntax should we prefer in ImageMagick scripts (for example, when using magick identify
): with ()
, which is supported by both ImageMagick and Zsh/Bash, or with {}
, which is supported by ImageMagick only?
A summary of my and Fred's (fmw42) tests
Bash | Zsh | |
---|---|---|
magick identify *.(jpg|png) |
– | ✓ |
magick identify *.{jpg,png} |
✓ | ✓† |
magick identify "*.{jpg,png}" |
✓ | ✓ |
Bash | Zsh | |
---|---|---|
file *.(jpg|png) |
– | ✓ |
file *.{jpg,png} |
✓‡ | ✓† |
file "*.{jpg,png}" |
– | – |
✓ - Works. You can have a) both JPGs and PNGs or b) PNGs only or c) JPGs only or d) none
✓† - Works, but you must have at least one JPG and one PNG
✓‡ - Works, but if you don't have at least one JPG and one PNG, there will be a warning
– - Doesn't work
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23)
zsh 5.9 (x86_64-apple-darwin23.0)
On my M1 Mac OSX Ventura in bash, I get
magick identify -format "%f: %m\n" *.(jp*|png|webp)
bash: syntax error near unexpected token `('
but
magick identify -format "%f: %m\n" "*.{jp*,png,webp}"
barn.jpg: JPEG
image.png: PNG
lena.jpg: JPEG
lena.png: PNG
mandril3.jpg: JPEG
monet2.jpg: JPEG
redhat.jpg: JPEG
zelda1.jpg: JPEG
So it seems to me that the latter is better in bash.
In zsh, I get
magick identify -format "%f: %m\n" *.(jp*|png|webp)
barn.jpg: JPEG
image.png: PNG
lena.jpg: JPEG
lena.png: PNG
mandril3.jpg: JPEG
monet2.jpg: JPEG
redhat.jpg: JPEG
zelda1.jpg: JPEG
and
magick identify -format "%f: %m\n" "*.{jp*,png,webp}"
barn.jpg: JPEG
image.png: PNG
lena.jpg: JPEG
lena.png: PNG
mandril3.jpg: JPEG
monet2.jpg: JPEG
redhat.jpg: JPEG
zelda1.jpg: JPEG
So zsh does a better job than bash with the () notation and the same as in bash with the {} notation
In bash for find, I get
file *.(jp*|png|webp)
bash: syntax error near unexpected token `('
and
file "*.{jp*,png,webp}"
*.{jp*,png,webp}: cannot open `*.{jp*,png,webp}' (No such file or directory)
and
For zsh for find, I get
file *.(jp*|png|webp)
barn.jpg: JPEG image data, JFIF standard 1.01, resolution (DPCM), density 28x28, segment length 16, comment: "bdh 11110000110100001100100011001010110110011100100101001101011011101010101010101011100111011001101001110000011111000101110010", baseline, precision 8, 400x299, components 3
image.png: PNG image data, 314 x 88, 8-bit/color RGBA, non-interlaced
lena.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, baseline, precision 8, 256x256, components 3
lena.png: PNG image data, 256 x 256, 8-bit/color RGB, non-interlaced
mandril3.jpg: JPEG image data, JFIF standard 1.01, resolution (DPCM), density 28x28, segment length 16, baseline, precision 8, 256x256, components 3
monet2.jpg: JPEG image data, baseline, precision 8, 265x333, components 3
redhat.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, baseline, precision 8, 254x255, components 3
zelda1.jpg: JPEG image data, JFIF standard 1.01, resolution (DPCM), density 28x28, segment length 16, baseline, precision 8, 256x256, components 3
and
file "*.{jp*,png,webp}"
*.{jp*,png,webp}: cannot open `*.{jp*,png,webp}' (No such file or directory)