3138

Bashに文字列があります:

string="My string"

別の文字列が含まれているかどうかをテストするにはどうすればよいですか?

if [ $string ?? 'foo' ]; then
  echo "It's there!"
fi

??不明なオペレーターはどこですか。と を使用echogrepますか?

if echo "$string" | grep 'foo'; then
  echo "It's there!"
fi

それは少し不器用に見えます。

4

27 に答える 27

4393

二重括弧を使用すると、ケースステートメントの外側でもマーカスの回答 (* ワイルドカード)を使用できます。

string='My long string'
if [[ $string == *"My long"* ]]; then
  echo "It's there!"
fi

針文字列内のスペースは二重引用符で囲む必要があり、*ワイルドカードは外側にある必要があることに注意してください。==また、正規表現 operator ではなく、単純な比較演算子 (つまり ) が使用されていることにも注意してください=~

于 2008-10-23T12:55:24.963 に答える
839

正規表現のアプローチを好む場合:

string='My string';

if [[ $string =~ "My" ]]; then
   echo "It's there!"
fi
于 2008-10-23T20:10:53.493 に答える
445

if ステートメントの使用についてはよくわかりませんが、case ステートメントを使用して同様の効果を得ることができます。

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac
于 2008-10-23T12:47:04.310 に答える
176

シェル スクリプトは言語ではなく、コマンドの集合であることに注意してください。あなたは本能的に、この「言語」では の後ifに a[またはを付ける必要があると思います[[。どちらも、成功または失敗を示す終了ステータスを返す単なるコマンドです (他のすべてのコマンドと同様)。そのためgrep、コマンドではなく を使用し[ます。

ただ行う:

if grep -q foo <<<"$string"; then
    echo "It's there"
fi

ifその後に続くコマンド (セミコロンで補完) の終了ステータスをテストすることを考えているので、テストしている文字列のソースを再考してみませんか?

## Instead of this
filetype="$(file -b "$1")"
if grep -q "tar archive" <<<"$filetype"; then
#...

## Simply do this
if file -b "$1" | grep -q "tar archive"; then
#...

戻りコードのみが必要なため、この-qオプションにより grep は何も出力しません。<<<シェルに次の単語を展開させ、それをコマンドへの入力として使用させます。これは、<<ヒア ドキュメントの 1 行バージョンです (これが標準なのか Bashism なのかはわかりません)。

于 2008-10-27T14:57:44.833 に答える
98

受け入れられた答えが最善ですが、それを行う方法は複数あるため、別の解決策を次に示します。

if [ "$string" != "${string/foo/}" ]; then
    echo "It's there!"
fi

${var/search/replace}$var最初のインスタンスが見つかった場合は、 にsearch置き換えられますreplace(変更されません$var)。何も置き換えようとせfooず、文字列が変更されている場合は、明らかfooに検出されました。

于 2008-10-23T14:35:45.400 に答える
74

この質問に対する有用な解決策はたくさんありますが、どれが最速で、リソースの使用量が最も少ないのでしょうか?

このフレームを使用した繰り返しテスト:

/usr/bin/time bash -c 'a=two;b=onetwothree; x=100000; while [ $x -gt 0 ]; do TEST ; x=$(($x-1)); done'

毎回 TEST を置き換える:

[[ $b =~ $a ]]           2.92 user 0.06 system 0:02.99 elapsed 99% CPU

[ "${b/$a//}" = "$b" ]   3.16 user 0.07 system 0:03.25 elapsed 99% CPU

[[ $b == *$a* ]]         1.85 user 0.04 system 0:01.90 elapsed 99% CPU

case $b in *$a):;;esac   1.80 user 0.02 system 0:01.83 elapsed 99% CPU

doContain $a $b          4.27 user 0.11 system 0:04.41 elapsed 99%CPU

(doContain は F. Houri の回答にありました)

そして笑いのために:

echo $b|grep -q $a       12.68 user 30.86 system 3:42.40 elapsed 19% CPU !ouch!

したがって、単純な置換オプションは、拡張テストであろうとケースであろうと、予想どおりに勝ちます。ケースは携帯用です。

100000 grep にパイプアウトするのは、予想通り苦痛です! 必要のない外部ユーティリティの使用に関する古いルールが当てはまります。

于 2014-08-27T19:42:38.477 に答える
31

これも機能します:

if printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  printf "Found needle in haystack"
fi

そして、否定的なテストは次のとおりです。

if ! printf -- '%s' "$haystack" | egrep -q -- "$needle"
then
  echo "Did not find needle in haystack"
fi

このスタイルはもう少し古典的で、Bash シェルの機能にあまり依存していないと思います。

引数は純粋な POSIX パラノイアであり、or--などのオプションに似た入力文字列から保護するために使用されます。--abc-a

注: タイト ループでは、1 つ (または 2 つ) の個別のプロセスが作成され、パイプ経由で接続されるため、このコードは内部の Bash シェル機能を使用するよりもはるかに遅くなります。

于 2012-12-01T15:41:25.683 に答える
23

ポールがパフォーマンス比較で述べたように:

if echo "abcdefg" | grep -q "bcdef"; then
    echo "String contains is true."
else
    echo "String contains is not true."
fi

これは、Marcus が提供する回答の「case "$string" in」のように POSIX に準拠していますが、case ステートメントの回答よりもわずかに読みやすくなっています。また、これは case ステートメントを使用するよりもはるかに遅くなることに注意してください。ポールが指摘したように、ループで使用しないでください。

于 2014-12-31T22:32:14.613 に答える
20

これはどう:

text="   <tag>bmnmn</tag>  "
if [[ "$text" =~ "<tag>" ]]; then
   echo "matched"
else
   echo "not matched"
fi
于 2009-02-09T06:15:45.083 に答える
12

このスタックオーバーフローの回答は、スペースとダッシュ文字をトラップする唯一のものでした:

# For null cmd arguments checking   
to_check=' -t'
space_n_dash_chars=' -'
[[ $to_check == *"$space_n_dash_chars"* ]] && echo found
于 2013-08-26T10:13:42.567 に答える
12
[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"
于 2015-04-28T19:55:58.883 に答える
11

1つは次のとおりです。

[ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'
于 2011-11-11T05:51:10.990 に答える
6

受け入れられた答えは正しいですが、読んで理解するのは難しいです。
検索に関連する問題については、常に$haystackイディオムで $needle を使用する必要があります。提案された編集キューがいっぱいな
ので、これを投稿します。

haystack='There are needles here.'
if [[ "$haystack" == *"needle"* ]]; then
    echo "It's there!"
fi
于 2021-11-30T20:12:44.643 に答える
5

この機能が頻繁に必要になることがわかったので.bashrc、覚えやすい名前で、必要に応じて何度でも再利用できるように、このような自家製のシェル関数を使用しています。

function stringinstring()
{
    case "$2" in
       *"$1"*)
          return 0
       ;;
    esac
    return 1
}

$string1( abc$string2など) が( 123abcABC など) に含まれているかどうかをテストするには、実行して戻り値を確認するだけですstringinstring "$string1" "$string2"。たとえば、

stringinstring "$str1" "$str2"  &&  echo YES  ||  echo NO
于 2012-07-01T11:31:45.450 に答える
5

私はセドが好きです。

substr="foo"
nonsub="$(echo "$string" | sed "s/$substr//")"
hassub=0 ; [ "$string" != "$nonsub" ] && hassub=1

編集、ロジック:

  • sed を使用して、文字列から部分文字列のインスタンスを削除します

  • 新しい文字列が古い文字列と異なる場合、部分文字列が存在します

于 2016-03-03T19:12:33.617 に答える
5

grep -qはこの目的に役立ちます。

を使用して同じawk

string="unix-bash 2389"
character="@"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

出力:

見つかりません

string="unix-bash 2389"
character="-"
printf '%s' "$string" | awk -vc="$character" '{ if (gsub(c, "")) { print "Found" } else { print "Not Found" } }'

出力:

見つかった

元のソース: http://unstableme.blogspot.com/2008/06/bash-search-letter-in-string-awk.html

于 2008-12-21T14:27:17.807 に答える
4
case $string in (*foo*)
  # Do stuff
esac

これはhttps://stackoverflow.com/a/229585/11267590と同じ答えです。シンプルなスタイルであり、POSIX 準拠でもあります。

于 2020-03-27T10:42:14.977 に答える
3

oobash を試してみてください。

Bash 4 用の OO スタイルの文字列ライブラリです。ドイツ語のウムラウトをサポートしています。バッシュで書かれています。

-base64Decode-base64Encode-capitalize-center-charAt-concat-contains-count-endsWith-equals-equalsIgnoreCase-reverse-hashCode-indexOf-isAlnum-isAlpha-isAscii-isDigit-isEmpty-isHexDigit-isLowerCase-isSpace-isPrintable、、および-isUpperCase_ -isVisible_ -lastIndexOf_ -length_ _ _ _ _ _ _ _ _ _-matches-replaceAll-replaceFirst-startsWith-substring-swapCase-toLowerCase-toString-toUpperCase-trim-zfill

次の例を見てください

[Desktop]$ String a testXccc
[Desktop]$ a.contains tX
true
[Desktop]$ a.contains XtX
false

oobash は Sourceforge.net で入手できます

于 2010-08-27T19:19:19.380 に答える