我在尝试返回符合参数的一个图像文件时遇到问题。 $1 是搜索参数,在本次事件中它是“真实的”,它是给定文件夹中的一张图像(而不是两张)上的标签。当我称之为“./test.sh real”时会发生什么,它会打印两张图像,而不仅仅是一张图像。我想它必须处理我将函数返回设置为变量和/或我的条件语句,但我不太确定。
#!/bin/bash
for f in specim/*.jpg
do
image=$(exiftool -EXIF:XPKeywords $f | grep "$1")
if [[ ! -z "$image// }" ]]; then
echo $f
fi
返回的内容:
../../test.sh real
specim/image2.jpg
specim/image.jpg
这个 bash 脚本打印出我想要的内容,只打印一个图像而不是两个图像(作为我不想要的 exiftool 东西,但这只是一个测试):
#!/bin/bash
for f in *.jpg
do
exiftool -EXIF:XPKeywords $f | grep $1
done
结果:
./test2.sh real
XP Keywords : name;real
任何帮助将不胜感激,这可能非常简单......谢谢
答案1
这可能正如您所怀疑的那样,只需进行一个小的更改即可修复,请尝试:
if [[ ! -z "$image" ]]; then
解释
假设当 exiftool 和 grep 匹配时,您的$image
变量包含以下内容:
abcabcabc
但是当没有输出时,$image
包含:(什么也没有)
在您的测试条件下,您有:
if [[ ! -z "$image// }" ]]; then
因此,在第一种情况下 bash 会看到:
if [[ ! -z "abcabcabc// }" ]]; then
但在第二种情况下,bash 会看到:
if [[ ! -z "// }" ]]; then
if "// }" is NOT zero-value, then...
然而测试表明"// }"
它总是不是零值,它是一个由两个斜杠、一个空格和一个大括号组成的字符串。因此,由于那里有一些东西,一些非零值的东西,这就是为什么then
即使 中没有匹配项也会触发该部分的原因$image
。因此,通过删除它// }
应该可以工作。
答案2
另一种选择可能是:
if [[ -n "$image" ]]; then
检查$image
变量是否仅包含某些内容,而不是! -z ...
答案3
您正在为该目录中的每个运行(+测试和回显)...不是很有效...exiftool
可以grep
通过选项自行完成所有操作,例如.jpg
exiftool
-if EXPR
exiftool -q -s3 -if '$tag=~/pattern/' -filename ./*.jpg
-q
(这里与-quiet 和-short 输出格式结合-s[NUM]
:仅打印值,有关更多详细信息,请参阅手册)
因此,在您的特定情况下,整个脚本可以替换为:
exiftool -q -s3 -if \$Exif:XPKeywords=~/"$1"/ -filename specim/*.jpg
test.sh
例如,使用四个具有以下值的测试文件运行脚本XPKeywords
:
exiftool -Exif:XPKeywords specim/*.jpg
======== specim/1.jpg
XP Keywords : xname;real
======== specim/2.jpg
XP Keywords : yname;different
======== specim/3.jpg
XP Keywords : wname;true
======== specim/4.jpg
XP Keywords : wname;unreal
4 image files read
运行test.sh real
返回:
1.jpg
4.jpg
并test.sh unreal
返回:
4.jpg
答案4
grep
的退出状态是它是否匹配某些内容,那么为什么要捕获 grep 的输出,然后以字符串形式测试它是否为空?你可以做
if exiftool -EXIF:XPKeywords $f | grep -q "$1" ; then
echo $f
fi
如果你愿意的话。