これが私が大事にしているものです:
#!/bin/sh
contains() {
if $(echo $1 | grep -c $2) ; then
echo "0" # contains
else
echo "1" # not contains
fi
}
myString=$1
mySubsting=$2
contains $myString '$mySubsting'
実行例は次のとおりです。
# sh ./myScript abcdef bc
./myTest: line 3: 0: command not found
1
編集:
元の質問は:Bourne Shellで文字列に部分文字列が含まれているかどうかを確認する方法
これが私が大事にしているものです:
#!/bin/sh
if echo $1 | grep -q $2
then
echo "0"
else
echo "1"
fi
実行例は次のとおりです。
$ sh ./myTest "$(systemctl status ntp)" "Active: active"
grep: active: No such file or directory
1
ある文字列に別の文字列が含まれているかどうかを適切に確認するにはどうすればよいですか?
ボーンシェルにはそのための構造がありました。これは、最近のsh
と同じです(これは、使用しているものに似ていますが、Bourne Shellは$(...)
をサポートしていませんでした。BourneShellの場合は、別のエラー):
case $1 in
*"$2"*) printf '"%s" is in "%s"\n' "$2" "$1"
esac
grep
を使用したい場合は、次のようになります。
if printf '%s\n' "$1" | grep -Fqe "$2"; then
printf '"%s" is in "%s"\n' "$2" "$1"
fi
または
if grep -Fqe "$2" << EOF
$1
EOF
then
printf '"%s" is in "%s"\n' "$2" "$1"
fi
しかし、これは$2
に改行文字が含まれていない場合にのみ正しく機能します。
いずれの場合も、これらのパラメーター展開のほとんどを引用符で囲む必要があります。それが不要な唯一の場所は、上のcase $1
内ですが、それでもcase "$1"
が害を及ぼすことはありません。
コードに関する注意事項:
echo
を使用できません 。ここでは、echo
の実装に応じて、$1
や-n
などのfoo\bar
の値に対して失敗します。grep -c $2
または$2
のような*
の値を持つroot /etc/passwd
を試してください。-F
なしのgrep
は、正規表現照合用です。固定文字列(部分文字列)の検索には-F
が必要です(以前はfgrep
で使用されていました)が、$2
に複数の行が含まれている場合、grep -F
にそれらの内容のanyを検索するように指示します入力の行(grep -F $'a\nb'
は$'a\nb'
文字列ではなくa
またはb
を検索します)。grep -c $2
では、$2
で始まっている場合、-
の内容はオプションとして扱われます。 grep -c -e "$2"
またはgrep -c -- "$2"
でそれを回避する必要があります。exit
(trueの場合はexit 0
、falseの場合はexit 1
(または0以外の数値。ただし、120より大きい値は避けてください)を含むスクリプトでは、falseの場合)。関数の場合は、代わりにreturn
を使用します。ただし、スクリプトと関数の両方が、最後に実行されたコマンドのステータスで返されます。$(cmd)
expandscmd
の出力(および引用符がないため、ここでsplit + globが実行されます)から末尾の改行文字を差し引いたもの。したがって、cmd
が0\n
を出力する場合、$(cmd)
は0
に展開されます。したがって、$(cmd)
を実行すると、0
というコマンドを実行しようとします。 cmd
の出力を終了ステータスに変換する(ブール値として使用できるようにする)には、(exit "$(cmd)")
が必要です。これにより、cmd
の出力を終了コードとして終了するサブシェルが開始されます)。grep -c
は、発生回数をカウントします。ここでは、完全な数を取得する必要はありません。それが見つかったかどうか(少なくとも1つの一致がある場合)を知るだけで済みます。そのため、grep -q
は、検索後に検索を停止するため、より効率的です。 (標準の)-q
オプションをサポートしない古いgrep
実装では、fgrep -le "$2" > /dev/null
を使用できます。 -l
を使用すると、fgrep
も最初の一致で停止しますが、ファイル名を出力します(ここでは、出力を/dev/null
にリダイレクトして破棄します)。bashはこれをネイティブでサポートしています。
$ string1="abcmoocow"
$ string2="moo"
$ if [[ $string1 == *$string2* ]]; then echo "Match"; else echo "No Match"; fi
Match
$ string1="abccrowcow"
$ if [[ $string1 == *$string2* ]]; then echo "Match"; else echo "No Match"; fi
No Match
あなたの例を修正するためにも;変化する;
if $(echo $1 | grep -c $2) ; then
になる:
if [ -n "$(echo $1 | grep -c $2)" ]; then
(grepがデータを返すかどうかを確認します)
また、終了コードを操作することもできます。
$ echo bob | grep "o" &>/dev/null; echo $?
0
$ echo bob | grep "z" &>/dev/null; echo $?
1
関数のポータブル(ダッシュ、バッシュ、kshなど)ソリューションは次のとおりです。
contains(){if ["$ {1 ## " $ 2 "}"];次に0をエコーします。それ以外の場合は1をエコーします。 #0は含む