重击条件:如何“和”表达?(如果[!-z $ VAR && -e $ VAR])


281

我想我不清楚如何进行“和”测试。我想确保存在一个与配合良好的参数[ -e $VAR ],但事实证明,该参数对空字符串的评估也为true;我不想要的。

如何将它们“和”在一起?还是有另一个一元测试可以实现我想要的功能?

Answers:



70

bash联机帮助页:

[[ expression ]] -根据条件表达式的计算结果,返回状态0或1。

并且,对于表达式,选项之一是:

expression1 && expression2-如果true expression1expression2true均为true。

因此,您可以and按以下步骤将它们放在一起(-n是的相反,-z因此我们可以摆脱!):

if [[ -n "$var" && -e "$var" ]] ; then
    echo "'$var' is non-empty and the file exists"
fi

但是,我认为在这种情况下不需要它,-e xyzzy如果xyzzy 文件存在并且可以很容易地处理空字符串,则为true 。如果这就是您想要的,那么您实际上不需要-z非空检查:

pax> VAR=xyzzy
pax> if [[ -e $VAR ]] ; then echo yes ; fi
pax> VAR=/tmp
pax> if [[ -e $VAR ]] ; then echo yes ; fi
yes

换句话说,只需使用:

if [[ -e "$var" ]] ; then
    echo "'$var' exists"
fi

1
我们可以用[[ -e "$var" ]] && echo "'$var' exists"
jaypal singh

1
是的,如果它是单线的(如我的示例所示)。如果条件块要复杂得多,我不会这样做。
paxdiablo 2012年

如果只有一个命令-甚至可能是一个长命令-使用这种格式是很有意义的,因为它较短
-avp

9
if [ -n "$var" -a -e "$var" ]; then
    do something ...
fi

 


10
由于POSIX未定义[复杂测试集的行为,因此应避免使用-a-o[。我在这里读过。
jaypal singh's

2
@ jaypal-singh是的,但是主题带有bash标签,并且没有提及POSIX,因此我发布了该版本,该版本可在bash其他一些现代shell下使用。
Slava Semushin 2012年

2
如果您假设使用bash或其他现代外壳,则建议的理由就更少-a
chepner 2014年

即使使用bash,这些测试的行为方式也并非在所有极端情况下都明确定义。考虑[ "$var1" -o "$var2" ]; 如果var1=(var2=),那么我们有什么是是否测试-o非空,而不是是否任一var1var2不为空。这种含糊不清是x$var成语在现代(即90年代后)test命令中使用正确引号的唯一成因,并且该成语需要大火。
查尔斯·达菲

4

只需引用您的变量:

[ -e "$VAR" ]

计算结果为[ -e "" ]if $VAR为空。

您的版本无效,因为它的评估结果为[ -e ]。现在,在这种情况下,bash仅检查单个参数(-e)是否为非空字符串。

从联机帮助页:

使用基于参数数量的一组规则测试和评估条件表达式。...

1个论点

当且仅当参数不为null时,表达式才为true。

(此外,此解决方案还有使用包含空格的文件名的额外好处)


1

我现在找到了答案。感谢您的建议!

for e in ./*.cutoff.txt; do
if grep -q -E 'COX1|Cu-oxidase' $e
then
    echo xyz >$e.match.txt
else
    echo
fi

if grep -q -E 'AMO' $e
then
    echo abc >$e.match.txt
else
    echo
fi; done

对此有何评论?两次grep似乎效率不高,但是可以工作...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.