即使 grep 不应返回任何内容,Bash 脚本条件也始终会通过

即使 grep 不应返回任何内容,Bash 脚本条件也始终会通过

我在尝试返回符合参数的一个图像文件时遇到问题。 $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

如果你愿意的话。

相关内容