Bashで文字列に部分文字列が含まれているかどうかを確認する方法


2570

私はバッシュに文字列があります:

string="My string"

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

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

??私の知らないオペレーターはどこですか。エコーを使用しgrepますか?

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

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


4
こんにちは、空の文字列が偽である場合、なぜそれを不格好だと思いますか?提案された解決策にもかかわらず、それは私にとっては唯一の方法でした。
ericson.cepeda

1
exprここでコマンドを使用できます
cli__

4
:POSIXシェルのここでの1 stackoverflow.com/questions/2829613/...
sehe

回答:


3654

あなたは使用することができマーカスの回答(*ワイルドカード)を使用すると、二重括弧を使用している場合は、あまりにも、case文の外:

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

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


127
また、テストで!=に切り替えるだけで比較を逆にできることにも注意してください。答えてくれてありがとう!
クインテイラー

63
@ジョニック:シバンが見つからないか、として持っている可能性があります#!/bin/sh#!/bin/bash代わりに試してください。
追って通知があるまで一時停止。

10
大括弧と内容の間にスペースを残します。
ポールプライス

17
[[]]内の変数を引用符で囲む必要はありません。これも同様に機能します:[[$ string == $ needle ]] && echo found
Orwellophile

13
@Orwellophile 慎重に!への最初の引数では、二重引用符のみを省略できます[[ideone.com/ZSy1gZを
nyuszika7h

611

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

string='My string';

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

2
bashスクリプトでegrepの正規表現を置き換える必要があった場合、これは完全に機能しました。
blast_hardcheese

114
=~オペレータは、すでに試合のための文字列全体を検索します。.*ここのは余分です。また、引用符はバックスラッシュに、一般的に好ましい:[[ $string =~ "My s" ]]
bukzor

16
@bukzorの引用はバッシュ3.2以上の、ここで動作を停止:tiswww.case.edu/php/chet/bash/FAQ E14)。(引用符を使用して)変数に割り当ててから比較するのがおそらく最善です。このように:re="My s"; if [[ $string =~ $re ]]
seanf

36
文字列が含まれ ていないかどうかをテストしif [[ ! "abc" =~ "d" ]]ます。trueです。
KrisWebDev 2016年

1
テストが行​​われる順序が重要であることに注意してください。コードの次の行の出力は、フォワード2あろうnumber=2; if [[ "1, 2, 4, 5" = *${number}* ]]; then echo forward $number; fi; if [[ *${number}* = "1, 2, 4, 5" ]]; then echo backwards $number; fi;
Leest DER Douweヴァン

356

ifステートメントを使用するかどうかはわかりませんが、caseステートメントで同様の効果を得ることができます。

case "$string" in 
  *foo*)
    # Do stuff
    ;;
esac

76
posixシェルに移植できるので、これはおそらく最良のソリューションです。(別名バシズム)
テクノサウルス2014年

25
@technosaurus bashタグのみの質問で「bashism」を批判するのはかなり奇妙だと思います:)
PP

39
@PPこれは、より限定的なソリューションよりもより普遍的なソリューションを好むので、それほど批判ではありません。数年後、人々(私のような)がこの回答を探すために立ち寄り、元の質問よりも広い範囲で役立つものを見つけて喜んでいることを考慮してください。彼らがオープンソースの世界で言うように:「選択は良いです!」
Carl Smotricz、2016年

2
@ technosaurus、FWIW [[ $string == *foo* ]]は一部のPOSIX準拠のshバージョン(/usr/xpg4/bin/shSolaris 10など)とksh(> = 88)でも動作します
maxschlepzig

3
Busybox ashはアスタリスクを処理しません[[...ケーススイッチは機能しました!
Ray Foss

232

stringContain バリアント(互換またはケースに依存しない)

これらのスタックオーバーフローの回答は主にBashについて語っているので、この記事の一番下に、ケースに依存しない Bash関数を投稿しました...

とにかく、

互換性のある答え

Bash固有の機能を使用した回答はすでにたくさんあるので、BusyBoxのように、機能の低いシェルで作業する方法があります。

[ -z "${string##*$reqsubstr*}" ]

実際には、これは次のようになります。

string='echo "My string"'
for reqsubstr in 'o "M' 'alt' 'str';do
  if [ -z "${string##*$reqsubstr*}" ] ;then
      echo "String '$string' contain substring: '$reqsubstr'."
    else
      echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
  done

これはBash、DashKornShellksh)、ash(BusyBox)でテストされ、結果は常に次のようになります。

String 'echo "My string"' contain substring: 'o "M'.
String 'echo "My string"' don't contain substring: 'alt'.
String 'echo "My string"' contain substring: 'str'.

1つの機能に

@EeroAaltonenによって尋ねられたように、同じシェルでテストされた同じデモのバージョンは次のとおりです。

myfunc() {
    reqsubstr="$1"
    shift
    string="$@"
    if [ -z "${string##*$reqsubstr*}" ] ;then
        echo "String '$string' contain substring: '$reqsubstr'.";
      else
        echo "String '$string' don't contain substring: '$reqsubstr'."
    fi
}

次に:

$ myfunc 'o "M' 'echo "My String"'
String 'echo "My String"' contain substring 'o "M'.

$ myfunc 'alt' 'echo "My String"'
String 'echo "My String"' don't contain substring 'alt'.

通知:引用符や二重引用符をエスケープするか二重に囲む必要があります。

$ myfunc 'o "M' echo "My String"
String 'echo My String' don't contain substring: 'o "M'.

$ myfunc 'o "M' echo \"My String\"
String 'echo "My String"' contain substring: 'o "M'.

シンプルな機能

これはBusyBox、Dash、そしてもちろんBashでテストされました:

stringContain() { [ -z "${2##*$1*}" ]; }

次に今:

$ if stringContain 'o "M3' 'echo "My String"';then echo yes;else echo no;fi
no
$ if stringContain 'o "M' 'echo "My String"';then echo yes;else echo no;fi
yes

...または、@ Sjlverで指摘されているように、送信された文字列が空の場合、関数は次のようになります。

stringContain() { [ -z "${2##*$1*}" ] && [ -z "$1" -o -n "$2" ]; }

または、AdrianGünterのコメントで示唆されているように、-o切り替えを回避します。

stringContain() { [ -z "${2##*$1*}" ] && { [ -z "$1" ] || [ -n "$2" ];};}

最終(単純)関数:

そして、テストを反転させて、潜在的に高速化します。

stringContain() { [ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ];};}

空の文字列で:

$ if stringContain '' ''; then echo yes; else echo no; fi
yes
$ if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

ケース非依存(Bashのみ!)

大文字と小文字を区別せずに文字列をテストするには、各文字列を小文字に変換します。

stringContain() {
    local _lc=${2,,}
    [ -z "$1" ] || { [ -z "${_lc##*${1,,}*}" ] && [ -n "$2" ] ;} ;}

小切手:

stringContain 'o "M3' 'echo "my string"' && echo yes || echo no
no
stringContain 'o "My' 'echo "my string"' && echo yes || echo no
yes
if stringContain '' ''; then echo yes; else echo no; fi
yes
if stringContain 'o "M' ''; then echo yes; else echo no; fi
no

1
これを関数に適用するいくつかの方法を見つけることができれば、これはさらに良いでしょう。
Eero Aaltonen

2
@EeroAaltonen(新しく追加された)関数をどのように見つけますか?
F.ハウリ、2014年

2
知っている!見つける -name "*" | xargs grep "myfunc" 2> / dev / null
eggmatters 14

6
それはとても互換性があるので、これは素晴らしいです。ただし、1つのバグ:干し草の文字列が空の場合は機能しません。正しいバージョンはstring_contains() { [ -z "${2##*$1*}" ] && [ -n "$2" -o -z "$1" ]; } 最終的な考えです。空の文字列には空の文字列が含まれていますか?上記のバージョンは(-o -z "$1"一部であるため)はい。
Sjlver 2014年

3
+1。とても良い!私は注文stringContain()を変更しました{[-z "$ {1 ## * $ 2 *}"] && [-z "$ 2" -o -n "$ 1"]; }; 「どこを検索」「何を検索」。busyboxで作業します。上記の承認された回答がbusyboxでは機能しません。
user3439968 2014年

149

シェルスクリプトは言語ではなく、コマンドの集まりであることに注意してください。本能的には、この「言語」ではif[やを付ける必要があると思います[[。これらは両方とも、(他のすべてのコマンドと同様に)成功または失敗を示す終了ステータスを返すコマンドです。そのため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行のバージョンです(これが標準かバシズムかはわかりません)。


7
これらはここでは文字列と呼ばれます(3.6.7)バシズムだと思います
alex.pilon

10
Process Substitutionを 使用することもできますif grep -q foo <(echo somefoothing); then
larsr

echo変数を渡している場合は移植不可能であるが、使用するprintf '%s' "$string代わりに。
nyuszika7h 2014年

5
これのコストは非常に高くなりますgrep -q foo <<<"$mystring"。1フォークを暗示することecho $mystring | grep -q fooバシズムであり、2フォークを暗示することです(1つはパイプ用、もう1つは実行用/path/to/grep
F. Hauri

1
echo引数文字列にバックスラッシュシーケンスが含まれている場合、フラグのない@BrunoBronosky でも、予期しない移植性の問題が発生する可能性があります。echo "nope\c"一部のプラットフォームでは、他のプラットフォームと同様echo -e "nope"に機能することが期待されています。printf '%s' "nope"vsprintf '%s\n' 'nope\c'
Tripleee

92

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

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

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


5
上記のephemientのソリューション:> `if [" $ string "!=" $ {string / foo /} "]; 次に、「そこにある!」とエコーします。fi`は、BusyBoxのシェルashを使用する場合に便利です。一部のbashの正規表現が実装されていないため、受け入れられたソリューションはBusyBoxでは機能しません。
TPoschel

1
違いの不平等。かなり奇妙な考え!大好きです
nitinr708

1
ただし、文字列が 'foo'でない限り
venimus

私はこれと同じ解決策を自分で書いて(私の通訳はトップアンサーを採用しないため)、より良い解決策を探しに行きましたが、これを見つけました!
BuvinJ

56

それで、質問に対する多くの有用な解決策があります-しかし、どちらが最も速く/最も少ないリソースを使用しますか?

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

/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 grepsにパイプを張るのは、予想通りに苦痛です!必要なしに外部ユーティリティを使用するという古い規則が当てはまります。


4
きちんとしたベンチマーク。使用するように私を説得した[[ $b == *$a* ]]
Mad Physicist

2
私がこれを正しく読んでいる場合case、全体の時間消費が最小で勝利します。$b in *$aただし、アスタリスクがありません。バグを修正した[[ $b == *$a* ]]場合よりも少し速い結果が得られcaseますが、もちろん他の要因にも依存する可能性があります。
tripleee 2018

1
ideone.com/5roEVtでは、いくつかの追加のバグが修正された実験が行われ、別のシナリオ(実際には文字列が長い文字列に存在しない場合)のテストが行​​われています。結果はほぼ同じです。[[ $b == *$a* ]]高速でcaseあり、ほぼ同じくらい高速です(快適にPOSIX互換です)。
tripleee

28

これも機能します:

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パラノイアである--abcまたは-a

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


5
...しかし、OPはbashのどのバージョンを示すものではありません。たとえば、古いbash(solarisなど)には、これらの新しいbash機能が含まれていない場合があります。(私はこの正確な問題に遭遇しました(bash 2.0を使用するsolarisでbashパターンマッチングは実装されていません)
マイケル

2
echoは移植性がないため、printf '%s' "$haystack代わりに使用する必要があります。
nyuszika7h 14年

2
いいえ、echoリテラルテキスト以外は一切エスケープせずに、エスケープなしで回避してください-。うまくいくかもしれませんが、移植性はありません。オプションが設定さechoれているかどうかによって、bashの動作も異なりxpg_echoます。PS:以前のコメントで二重引用符を閉じるのを忘れていました。
nyuszika7h 2014

1
@kevinarpeわかりません、--POSIX仕様にprintfリストされていませんが、printf '%s' "$anything"とにかく使用して、文字$anythingが含まれている場合の問題を回避する必要があり%ます。
nyuszika7h 2015年

1
@kevinarpeそれに基づいて、おそらくそうです。
nyuszika7h

21

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

例8、ワイルドカード一致.ext(大文字と小文字を区別しない):

     if echo "$a" | egrep -iq "\.(mp[3-4]|txt|css|jpg|png)" ; then

楽しい。


17

これはどう:

text="   <tag>bmnmn</tag>  "
if [[ "$text" =~ "<tag>" ]]; then
   echo "matched"
else
   echo "not matched"
fi

2
=〜は正規表現マッチングのためのもので、OPの目的には強力すぎます。

16

ポールは述べた彼のパフォーマンスを比較して:

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

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



9
[[ $string == *foo* ]] && echo "It's there" || echo "Couldn't find"

echo "Couldn't find末尾のステートメントは、これらの一致するコマンドに対して0の終了ステータスを返す優れたトリックであることを付け加えます。
nicodjimenez 2017年

@nicodjimenezこのソリューションでは、終了ステータスをターゲットにすることはできません。終了ステータスはステータスメッセージによって飲み込まれます...
Jahid

1
それがまさに私が意味したことです...持っていない場合|| echo "Couldn't find"、一致がない場合はエラー終了ステータスを返します。たとえば、CIパイプラインを実行している場合、たとえばすべてのコマンドを返す必要がある場合は、これは望ましくありません。エラー以外の終了ステータス
nicodjimenez 2017年

9

1つは次のとおりです。

[ $(expr $mystring : ".*${search}.*") -ne 0 ] && echo 'yes' ||  echo 'no'

2
exprスイスアーミーナイフユーティリティの1つであり、その方法を理解すると、通常は必要なことを何でも実行できますが、一度実装すると、理由や方法が何をしているかを思い出すことはできません。二度と触れないでください。そして、それがやっていることをやめないことを願っています。
マイケル2013

@AloisMahdal私は反対票を投じなかった、私は反対票が与えられた理由を仮定しているだけだ。注意コメント。私は使用を行うexpr、まれに、ときはbashを使用して、移植の防止(例えば、古いバージョン間で一貫性のない動作)、TR(どこでも一貫性のない)または(ときには遅すぎる)のsed。しかし、個人的な経験から、これらのexprイズミズムを再読するときはいつでも、manページに戻る必要があります。だから、私はすべての用法exprがコメントされるとコメントするだけです...
マイケル・

1
あなたが持っていたすべてがオリジナルのボーンシェルであった時代がありました。一般的に必要とされるいくつかの機能が欠けていたため、exprおよびのようなツールtestがそれらを実行するために実装されました。この時代には、通常より良いツールがあり、それらの多くは現代のシェルに組み込まれています。testまだそこにぶら下がっていると思いますが、行方不明者はいないようexprです。
tripleee 2016

6

私はセッドが好きです。

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

編集、ロジック:

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

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


2
説明を追加してください。基になるロジックを提供することは、コードを提供することよりも重要です。これは、OPや他の読者がこの問題や同様の問題を自分自身で修正するのに役立つためです
Zulan

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


3
echoは移植性がないため、printf '%s' "$string"代わりに使用する必要があります。ユーザーがもう存在していないように見えるので、私は回答を編集しています。
nyuszika7h 2014年

echo@ nyuszika7h、どのように移植できないのですか?
starbeamrainbowlabs

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

[["$ str" == $ substr ]] &&エコーYES || エコーNO
elyase

xハックは非常に古いシェルのみ必要と確信しています。
nyuszika7h 2014年

5

私の.bash_profileファイルとgrepの使用方法:

PATH環境変数に2つのbinディレクトリが含まれている場合は、それらを追加しないでください。

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi

U=~/.local.bin:~/bin

if ! echo "$PATH" | grep -q "home"; then
    export PATH=$PATH:${U}
fi

1
これは答えですか?
codeforester 2017年

賛成票。grepがはるかに強力であるときにBashがどのように実行するかをわざわざ学ぶ必要があるのはなぜでしょうか。また、パターンのリストと照合することにより、さらに拡張しますgrep -q -E 'pattern1|...|patternN'
Mohamed Bana

4

ここで回答された質問の拡張文字列にPOSIX shの別の文字列が含まれているかどうかはどのようにしてわかりますか?

このソリューションは特殊文字で機能します:

# contains(string, substring)
#
# Returns 0 if the specified string contains the specified substring,
# otherwise returns 1.
contains() {
    string="$1"
    substring="$2"

    if echo "$string" | $(type -p ggrep grep | head -1) -F -- "$substring" >/dev/null; then
        return 0    # $substring is in $string
    else
        return 1    # $substring is not in $string
    fi
}

contains "abcd" "e" || echo "abcd does not contain e"
contains "abcd" "ab" && echo "abcd contains ab"
contains "abcd" "bc" && echo "abcd contains bc"
contains "abcd" "cd" && echo "abcd contains cd"
contains "abcd" "abcd" && echo "abcd contains abcd"
contains "" "" && echo "empty string contains empty string"
contains "a" "" && echo "a contains empty string"
contains "" "a" || echo "empty string does not contain a"
contains "abcd efgh" "cd ef" && echo "abcd efgh contains cd ef"
contains "abcd efgh" " " && echo "abcd efgh contains a space"

contains "abcd [efg] hij" "[efg]" && echo "abcd [efg] hij contains [efg]"
contains "abcd [efg] hij" "[effg]" || echo "abcd [efg] hij does not contain [effg]"

contains "abcd *efg* hij" "*efg*" && echo "abcd *efg* hij contains *efg*"
contains "abcd *efg* hij" "d *efg* h" && echo "abcd *efg* hij contains d *efg* h"
contains "abcd *efg* hij" "*effg*" || echo "abcd *efg* hij does not contain *effg*"

オプションとしてを飲み込むcontains "-n" "n"ため、テストはここでは機能しません。そのための一般的な修正は、代わりに使用することです。echo -n-nprintf "%s\n" "$string"
joeytwiddle

完全に、解決された文字列にはスペースが含まれていました
dengApro

4

POSIX / BusyBoxの質問は正しい答え(IMHO)を提供せずに閉じられているので、ここに答えを投稿します。

可能な限り短い答えは:

[ ${_string_##*$_substring_*} ] || echo Substring found!

または

[ "${_string_##*$_substring_*}" ] || echo 'Substring found!'

一部のシェル()では二重ハッシュ必須であることに注意してくださいash。上記は[ stringvalue ]、部分文字列が見つからない場合に評価されます。エラーは返されません。サブストリングが見つかると、結果は空になり、評価され[ ]ます。文字列が完全に置換されているため、これによりエラーコード1がスローされます(*)。

最も一般的で短い構文:

[ -z "${_string_##*$_substring_*}" ] && echo 'Substring found!'

または

[ -n "${_string_##*$_substring_*}" ] || echo 'Substring found!'

別のもの:

[ "${_string_##$_substring_}" != "$_string_" ] && echo 'Substring found!'

または

[ "${_string_##$_substring_}" = "$_string_" ] || echo 'Substring found!'

単一の等号に注意してください!


3

完全一致:

string='My long string'
exactSearch='long'

if grep -E -q "\b${exactSearch}\b" <<<${string} >/dev/null 2>&1
  then
    echo "It's there"
  fi

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から入手できます


2

私はこの関数を使用しています(1つの依存関係は含まれていませんが、明白です)。以下に示すテストに合格しています。関数が0より大きい値を返す場合、文字列が見つかりました。代わりに、簡単に1または0を返すこともできます。

function str_instr {
   # Return position of ```str``` within ```string```.
   # >>> str_instr "str" "string"
   # str: String to search for.
   # string: String to search.
   typeset str string x
   # Behavior here is not the same in bash vs ksh unless we escape special characters.
   str="$(str_escape_special_characters "${1}")"
   string="${2}"
   x="${string%%$str*}"
   if [[ "${x}" != "${string}" ]]; then
      echo "${#x} + 1" | bc -l
   else
      echo 0
   fi
}

function test_str_instr {
   str_instr "(" "'foo@host (dev,web)'" | assert_eq 11
   str_instr ")" "'foo@host (dev,web)'" | assert_eq 19
   str_instr "[" "'foo@host [dev,web]'" | assert_eq 11
   str_instr "]" "'foo@host [dev,web]'" | assert_eq 19
   str_instr "a" "abc" | assert_eq 1
   str_instr "z" "abc" | assert_eq 0
   str_instr "Eggs" "Green Eggs And Ham" | assert_eq 7
   str_instr "a" "" | assert_eq 0
   str_instr "" "" | assert_eq 0
   str_instr " " "Green Eggs" | assert_eq 6
   str_instr " " " Green "  | assert_eq 1
}

サスペンス!依存関係何ですか?
Peter Mortensen、

「str_escape_special_characters」関数。GitHubのarcshell_str.shファイルにあります。arcshell.ioを使用すると、そこにアクセスできます。
イーサンポスト


0
msg="message"

function check {
    echo $msg | egrep [abc] 1> /dev/null

    if [ $? -ne 1 ];
    then 
        echo "found" 
    else 
        echo "not found" 
    fi
}

check

これは、aまたはbまたはcの発生を検出します


0

一般的な針の干し草の例は、変数を使用しています

#!/bin/bash

needle="a_needle"
haystack="a_needle another_needle a_third_needle"
if [[ $haystack == *"$needle"* ]]; then
    echo "needle found"
else
    echo "needle NOT found"
fi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.