これが私が試していることです:
#!/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
文字列に他の文字列が含まれているかどうかを正しく確認するには?
答え1
関数を含む移植可能な(dash、bash、kshなど)スクリプト:
#!/bin/sh
contains() { if [ "$1" ] && # Is there a source string.
[ "$2" ] && # Is there a substring.
[ -z "${1##*"$2"*}" ]; # Test substring in source.
then echo 0; # Print a "0" for a match.
else echo 1; # Print a "1" if no match.
fi;
}
contains "$1" "$2"
ここで、0 は「含む」(真値)を意味します。
これは次のようにテストされます。
$ contains "test a simple line" simpl
1
$ contains "One sentence" "No more"
0
答え2
Bourneシェルにはこの目的のための設定があります。これは現代のものと同じですsh
(これはBourneシェルでサポートされていない使用中のものと似ています$(...)
。Bourneシェルの場合は他のエラーが発生します)。
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
grep
なしでは、-F
正規表現の一致に使用されます。-F
文字列(サブ文字列)検索(過去)を変更する必要がありますfgrep
が、$2
複数行が含まれている場合は再grep -F
検索する場合どの入力では、これらの行の内容は文字列ではなくorをgrep -F $'a\nb'
探します。a
b
$'a\nb'
- で
grep -c $2
始まると、内容は$2
オプションとして扱われます-
。あなたはこの状況を望むgrep -c -e "$2"
かgrep -c -- "$2"
避けます。 - ブール条件を報告するために標準出力の代わりに終了状態を使用しようとしています。スクリプトでは
exit
(exit 0
trueの場合exit 1
(またはゼロ以外の数字、120より大きい値を避ける)の場合はfalse)を使用します。機能の場合はreturn
代わりに使用してください。スクリプトと関数の両方が最後のコマンド実行状態を返します。 $(cmd)
拡大する末尾の改行を引いた出力cmd
(そして引用符が再び欠けて、ここで分割+globを経ること)です。したがって、cmd
出力がに拡張される0\n
と、runはというコマンドを実行しようとします。出力を終了状態に変換するには(ブール値として使用可能)、終了コードで出力として終了するサブシェルが起動します。$(cmd)
0
$(cmd)
0
cmd
(exit "$(cmd)")
cmd
grep -c
発生回数を計算します。ここでは、総数は必要なく、検索されたか(一致する項目が 1 つ以上あるか)を知るだけです。grep -q
見つかったら検索を停止するので、これはより効率的です。grep
(標準)オプションをサポートしていない以前の-q
実装では、最初の一致で停止しますが、ファイル名を出力するfgrep -le "$2" > /dev/null
.forを使用できます(ここでは出力をリダイレクトして削除します)。-l
fgrep
/dev/null
答え3
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