我知道我可以使用
file pic.jpg
来获取文件类型,但是如何编写 if
语句来在 shell 脚本中检查它?
例如(伪代码):
if pic.jpg == jpeg file then
尝试(假设 Bash v3.0+,使用
=~
,正则表达式匹配运算符):
if [[ $(file -b 'pic.jpg') =~ JPEG ]]; then ...
如果您想更紧密地匹配
file
的输出:
if [[ $(file -b 'pic.jpg') =~ ^'JPEG ' ]]; then ...
仅当输出以“JPEG”开头,后跟空格时才匹配。
或者,如果您更愿意使用通配样式模式:
if [[ $(file -b 'pic.jpg') == 'JPEG '* ]]; then ...
符合 POSIX 条件 ([ ... ]
)不提供正则表达式或模式匹配,因此需要不同的方法:
if expr "$(file -b 'pic.jpg')" : 'JPEG ' >/dev/null; then ...
注意:expr
仅支持basic正则表达式,并且隐式锚定在字符串的开头(不需要
^
)。或者,使用
case
语句,它支持模式匹配:
case "$(file -b 'pic.jpg')" in
'JPEG '*)
# ...
;;
esac
至于为什么 Bash 片段中需要 [[ ... ]]
而不是
[ ... ]
:高级功能,例如正则表达式运算符 (
=~
) 或模式匹配(例如,使用不带引号的
*
来表示任何字符序列。)是非标准的(不是 POSIX shell 规范的一部分)。由于这些功能与标准条件 (
[ ... ]
) 的工作方式不兼容,因此需要新的语法; Bash、Ksh 和 Zsh 使用
[[ ... ]]
。
case
也值得一提。
case $(file -b pic.jpg) in
'JPEG '*)
echo is
;;
*)
echo is not
;;
esac
单独的右括号一开始可能看起来很不可思议,但除此之外,这是相当简单、可读、通用且可移植的方式,可以追溯到原始的 Bourne shell。 (POSIX 也允许在表达式之前使用匹配的左括号。)
file -b
输出将
JPEG
作为该行的第一个单词:
pax> file -b somefile.jpg
JPEG image data, JFIF standard 1.01, blah blah blah
因此,您可以使用它来检测它,例如:
inputFile=somefile.jpg
if [[ $(file -b $testFile | awk '{print $1}') == "JPEG" ]] ; then
echo $inputFile is a JPEG file.
fi