Bashで文字列を比較する方法


回答:


1376

ifステートメントでの変数の使用

if [ "$x" = "valid" ]; then
  echo "x has the value 'valid'"
fi

あなたは、彼らが一致していない何かをしたい場合は、交換してください=!=文字列演算算術演算の詳細については、それぞれのドキュメントを参照してください。

なぜ引用符を使用するの$xですか?

$x空の場合、Bashスクリプトで以下のように構文エラーが発生するため、引用符で囲みます。

if [ = "valid" ]; then

==演算子の非標準的な使用

Bashはとの==等価に使用できます[が、これは標準ではないことに注意してください。

前後の引用符$xがオプションである最初のケースを使用します。

if [[ "$x" == "valid" ]]; then

または2番目のケースを使用します。

if [ "$x" = "valid" ]; then

12
それは、予期ないオペレーターエラーで与えられた受け入れられた回答とどのように関連していますか?を使用すると同じエラーが発生しました[ "$1" == "on" ]。これを["$ 1" = "on"]に変更すると、問題が解決しました。
Piotr Dobrogost 2013

78
スペースが必要です。
TAAPSogeking 2013

6
@JohnFeminella bashスクリプトで記述する場合、2つで=はなく1つにする必要があります。
user13107 2014

73
使用できないことに注意してください[ $x -eq "valid" ]-eq文字列ではなく整数の比較演算子です。
craq 2015

2
@Alex、(もしあれば)パターンを使用する必要がありますか?これ["x$yes" == "xyes"]は、変数と文字列リテラルの両方の前にx?それは昔の遺物ですか、それともいくつかの状況で本当に必要ですか?
lanoxx

142

または、else句が必要ない場合:

[ "$x" == "valid" ] && echo "x has the value 'valid'"

71
そして、else句が必要で、クレイジーな1行にしたい場合は、次のようにします。["$ x" == "valid"] && echo "valid" || エコー "無効"
マットホワイト

11
@MattWhite:echo失敗する可能性があるため、これは通常悪い考えです。
gniourf_gniourf 2016年

1
マルコとマットホワイトの両方から、美しくエレガントな方法で登場するかもしれないものも
Deko

3
@gniourf_gniourf、問題ありません [ "$X" == "valid" ] || ( echo invalid && false ) && echo "valid"
12431234123412341234123 2017

4
@ 12431234123412341234123 { echo invalid && false; }( echo invalid && false )、不要なサブシェルへの支払いを回避するため、よりも効率的です。
Charles Duffy

84
a="abc"
b="def"

# Equality Comparison
if [ "$a" == "$b" ]; then
    echo "Strings match"
else
    echo "Strings don't match"
fi

# Lexicographic (greater than, less than) comparison.
if [ "$a" \< "$b" ]; then
    echo "$a is lexicographically smaller then $b"
elif [ "$a" \> "$b" ]; then
    echo "$b is lexicographically smaller than $a"
else
    echo "Strings are equal"
fi

ノート:

  1. スペースの間if[して]重要であり、
  2. >および<はリダイレクト演算子であるため、文字列\>\<それぞれエスケープします。

6
文字列のアルファベット順の比較をありがとう
shadi

私の問題は、文字列リテラル値の一部として$a実際に" "囲まれていたため、エスケープ文字を使用し$bて値を比較する必要がありました。実行後にこれを見つけることができましbash -x ./script.shた。-xフラグを使用すると、各実行の値を確認でき、デバッグに役立ちます。
ShahNewazKhan 2017

アルファベット順の比較はPOSIXで標準化されていないため、GNU以外のプラットフォーム/ bash以外のシェルでの動作は保証されていません。移植性が保証されているのは、pubs.opengroup.org / onlinepubs / 9699919799 / utilities / test.htmlでの操作のみです。
Charles Duffy

62

文字列とワイルドカードを比較するには

if [[ "$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do Something here
fi

12
ワイルドカードは右側でのみ使用できることが重要です。"ワイルドカードの周りの欠落にも注意してください。(ところで:ワイルドカードの場合は+1!)
2015年

6
展開$stringB 引用符で囲む必要あります(偶然にも、左側を引用符で囲む必要はありません)if [[ $stringA = *"$stringB"* ]]; then
gniourf_gniourf 2016年

ファイルパスのファイル名に同じワイルドカードロジックを使用しようとしています。しかし、それは私のために働いていません。ここで提供されるすべての異なるワイルドカード文字列を試しました。しかし、それは常に他のケースに行きます。私の場合、stringAはファイルパス/ tmp / fileで、stringBは「file」です。

35

私は一点でコメントの1つに同意しなければなりません:

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

いいえ、それはクレイジーなワンライナーではありません

それはただのようです、うーん、初心者...

ある意味、言語として一般的なパターンを使用しています。

そしてあなたが言語を学んだ後。

実は読むのはいいです

これは、論理演算子の遅延評価という1つの特別な部分を持つ単純な論理式です。

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

各部分は論理式です。最初の2つはtrueまたはfalseで、他の2つは常にtrueです。

(
[ "$x" == "valid" ] 
&&
echo "valid"
)
||
echo "invalid"

今、それが評価されるとき、最初がチェックされます。それはロジックの第二オペランドよりも、偽の場合 &&した後、それは関係ありません。最初のものは真実ではないので、とにかくそれが最初のものであり、2番目のものが真であることはありえません。
ここで、この場合はロジックの最初の側 または || falseですが、反対側(3番目の部分)がtrueの場合はtrueになる可能性があります。

したがって、3番目の部分が評価されます-主に副作用としてメッセージを書き込む。(0true の結果がありますが、ここでは使用しません)

他のケースも同様ですが、単純です-そして-私は約束します!ある-できる-読みやすい!
(私は持っていませんが、灰色のひげを持つUNIXのベテランであることは、これで多くの助けになると思います。)


17
... && ... || ...通常時に難色され、それが意味的に等価ではないとして、(ごめん老いUnixのベテラン、あなたはすべてのこの時間のために間違ってました)if ... then ... else ...。心配しないでください。これはよくある落とし穴です。
gniourf_gniourf 2016年

6
@gniourf_gniourf OPが間違っているわけではありません。 ... && ... || ...完全に有効なパターンであり、一般的なbashイディオムです。これを使用すると事前の知識が規定されますが(オーディエンスに初心者がいる場合は覚えておくとよいかもしれません)、OPには、開いたマンホールの蓋を回避する方法を知っていることを証明するための毛があります。
ebpa 2017年

3
@ebpa &&に続くステートメントがfalseの値を返す場合、||に続くステートメントに実行が移ります。?もしそうならそれは間違っており、おそらくgniourfが示唆していることです
TSG

4
エコーはほんの一例だと思いました。&&に続くステートメントは、ゼロ以外の値を返す可能性があります
TSG

2
@gniourf_gniourf +1 Bash Pitfallsへのリンクを投稿してください!非常に便利!
ジャガー

21

ユースケース/ esacを使用することもできます

case "$string" in
 "$pattern" ) echo "found";;
esac

これは同等ですか、それとも含まれていますか?
ytpillai

@ytpillai、それは同値です。の|前に、で区切られたパターンがあることに注意してください)。このinステートメントは、thenin ステートメントと同等ifです。あなたがPythonから来た場合、各リストが何をすべきかについての独自の宣言を持っているパターンのリストに対して機能することを主張することができます。好きsubstring in stringではなく、むしろfor item in list。条件*が必要な場合は、最後のステートメントとしてa を使用しますelse。最初の出会いに戻ります。
mazunki

18

次のスクリプトは、「testonthis」という名前のファイルから1行ずつ読み取り、各行を単純な文字列、特殊文字を含む文字列、および正規表現と比較します。一致しない場合、スクリプトは行を印刷します。それ以外の場合は一致しません。

バッシュのスペースはとても重要です。したがって、以下が機能します:

[ "$LINE" != "table_name" ] 

ただし、次のことはできません。

["$LINE" != "table_name"] 

そのまま使用してください:

cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done

このアプローチを使用して、ファイルを調べます。つまり、とりわけUUoCを削除します。
fedorqui 'SO stop harming' 2016

これは重要ではありませんbashが、[実際には外部バイナリであるので(のwhich [ようなものが生成されます/usr/bin/[
Patrick Bergner

11

入力に有効なエントリが少ししかない場合、おそらく正規表現一致を使用します。たとえば、「開始」と「停止」のみが有効なアクションです。

if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
  echo "valid action"
fi

$ACTION二重コンマを使用して変数を小文字にしています。また、これは古すぎるbashバージョンでは機能しないことに注意してください。


9

Bash 4+の例。注:引用符を使用しないと、単語にスペースなどが含まれている場合に問題が発生します。常にBash、IMOで引用してください。

以下は、Bash 4+の例です。

例1、文字列の「yes」を確認します(大文字と小文字は区別されません)。

    if [[ "${str,,}" == *"yes"* ]] ;then

例2、文字列の 'yes'を確認します(大文字と小文字は区別されません)。

    if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

例3、文字列の「yes」を確認します(大文字と小文字を区別):

     if [[ "${str}" == *"yes"* ]] ;then

例4、文字列の「yes」を確認します(大文字と小文字を区別):

     if [[ "${str}" =~ "yes" ]] ;then

例5、完全一致(大文字と小文字を区別):

     if [[ "${str}" == "yes" ]] ;then

例6、完全一致(大文字と小文字を区別しない):

     if [[ "${str,,}" == "yes" ]] ;then

例7、完全一致:

     if [ "$a" = "$b" ] ;then

楽しい。


私のために(MAC GNUのbashのバージョン4.4.12(1)-releaseはx86_64-リンゴ-darwin17.0.0)、私が使用する必要がありますif [ "$a"="$b" ]か、それは仕事が...等号の周りにスペースを入れることはできませんしません
スペクトル

1

私はBashおよびDash(sh)と互換性のある方法でそれを行いました:

testOutput="my test"
pattern="my"

case $testOutput in (*"$pattern"*)
    echo "if there is a match"
    exit 1
    ;;
(*)
   ! echo there is no coincidence!
;;esac

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