Bash条件文:式の「および」方法 (if [!-z $ VAR && -e $ VAR])


281

「and」テストを行う方法が明確でないと思います。でうまく機能する引数が存在することを確認したかったの[ -e $VAR ]ですが、空の文字列でもtrueと評価されていることがわかりました。私は欲しくない。

どうすれば一緒に「そして」できますか?または、私が望むものを達成する別の単項テストはありますか?

回答:


532
if [ ! -z "$var" ] && [ -e "$var" ]; then
      # something ...
fi

9
このソリューションは、厳密にPOSIX準拠のシェルでも機能するため、でも機能しbashます。ただし、「バシズム」を最大限に活用するには、@ paxdiabloの回答を参照してください。
mklement0 2014

2
陳腐化し-aたものの代わりにこれが助言されるのを見てとても嬉しい。
Charles Duffy

1
私は別のものに優れて詳細な説明を見つけた- stackoverflow.com/questions/3601515/...
valentt

70

bashマンページから:

[[ expression ]] -条件式expressionの評価に応じて、0または1のステータスを返します。

そして、式の場合、オプションの1つは次のとおりです。

expression1 && expression2- expression1との両方expression2が真の場合は真。

したがってand、次のようにまとめることができます(-nの反対な-zので、を取り除くことができます!)。

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

ただし、この場合-e xyzzyは必要ないと思いxyzzy ます。ファイルが存在し、空の文字列を非常に簡単に処理できる場合はそうです。それが必要な場合は、実際には-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 sing 2012

1
はい、それが(私の例のように)ワンライナーの場合は。ただし、条件付きブロックがはるかに複雑な場合は、そうしません。
paxdiablo 2012年

多分長い1 - -の場合には1つだけであるコマンドは、それが短いほど、このフォームを使用するように理にかなって
AVP

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

 


10
以来POSIXの動作は定義されていません[テストの複雑なセットでは、我々は使用を避けるべき-a-o[ここで読む。
jaypal sing 2012

2
@ jaypal-singhその通りですが、トピックにはbashタグがあり、POSIXについて言及されていないため、このバージョンとbash他のいくつかの最新のシェルで動作するバージョンを投稿します。
Slava Semushin 2012年

2
bashまたは他の最新のシェルの使用を想定している場合、推奨する理由はさらに少なくなり-aます。
chepner 2014

bashを使用しても、これらのテストの動作は、すべての例外的なケースで明確に定義されているわけではありません。考えなさい[ "$var1" -o "$var2" ]; if var1=(との場合、またはが空でないかどうかではなく、空でないvar2=)かどうかをテストします。この種のあいまいさは、現代(つまり90年代以降)のコマンドで正しい引用符が付けられたイディオムの唯一の正当な理由であり、そのイディオムは火事で死ぬ必要があります。-ovar1var2x$vartest
Charles Duffy

4

変数を引用するだけです:

[ -e "$VAR" ]

これは空[ -e "" ]かどうかを評価し$VARます。

はと評価されるため、バージョンは機能しません[ -e ]。この場合、bashは単一の引数(-e)が空でない文字列であるかどうかを確認するだけです。

マンページから:

testと[は、引数の数に基づく一連のルールを使用して条件式を評価します。...

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

何かコメントはありますか?2回grepするのは効率が悪いようですが、うまくいきます...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.