I know I can use file pic.jpg
to get the file type, but how do I write an if
statement to check it in a shell script?
E.g. (pseudo code):
if pic.jpg == jpeg file then
Try (assumes bash
(v3.0+), zsh
, or ksh
) , using =~
, the regex-matching operator):
if [[ $(file -b 'pic.jpg') =~ JPEG ]]; then ...; fi
If you want to match file
's output more closely:
if [[ $(file -b 'pic.jpg') =~ ^'JPEG ' ]]; then ...; fi
This will only match if the output starts with 'JPEG', followed by a space.
Alternatively, if you'd rather use a globbing-style (wildcard) pattern:
if [[ $(file -b 'pic.jpg') == 'JPEG '* ]]; then ...; fi
POSIX-compliant conditionals ([ ... ]
) do not offer regex or pattern matching, so a different approach is needed:
if expr "$(file -b 'pic.jpg')" : 'JPEG ' >/dev/null; then ...; fi
Note: expr
only supports basic regular expressions and is implicitly anchored at the start of the string (no need for ^
).
Alternatively, use a case
statement, which does support pattern matching per POSIX, as also shown in triplee's helpful answer:
case "$(file -b 'pic.jpg')" in
'JPEG '*)
# ...
;;
esac
As for why [[ ... ]]
rather than [ ... ]
is needed in the Bash snippets:
Advanced features such as the regex operator (=~
) or pattern matching (e.g., use of unquoted *
to represent any sequence of chars.) are nonstandard (not part of the POSIX shell specification).
Since these features are incompatible with how standard conditionals ([ ... ]
) work, a new syntax was required; Bash, Ksh, and Zsh use [[ ... ]]
.