コマンド出力で大文字と小文字を区別しない部分文字列一致を実行するシェルスクリプトをどのように記述できますか?
答え1
シェルオプションを設定すると、bash
正規表現演算子を使用してデフォルトで大文字と小文字を区別しない部分文字列照合を実行できます。例えば=~
nocasematch
s1="hElLo WoRlD"
s2="LO"
shopt -s nocasematch
[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
match
s1="gOoDbYe WoRlD"
[[ $s1 =~ $s2 ]] && echo "match" || echo "no match"
no match
答え2
まず、大文字と小文字を無視しない単純なサンプルスクリプトは次のとおりです。
#!/bin/bash
if [ $(echo hello) == hello ]; then
echo it works
fi
右側のhello文字列を変更してみると、echoは発生しなくなりますit works
。echo hello
必要なコマンドに置き換えてみてください。大文字と小文字を無視して文字列に改行文字が含まれていない場合は、grepを使用できます。
#!/bin/bash
if echo Hello | grep -iqF hello; then
echo it works
fi
ここで重要なのは、コマンド出力をにパイプすることですgrep
。このif
ステートメントは、パイプの右端のコマンド(この場合はgrep)の終了状態をテストします。 Grepは、一致するものが見つかった場合にのみ正常に終了します。
grepオプションは-i
大文字と小文字を無視することを意味します。
この-q
オプションは、出力をエクスポートせず、最初の一致後に終了することを意味します。
この-F
オプションは、引数を正規表現ではなく文字列として扱うことを意味します。
最初の例では、直接比較が可能な演算子と多様で有用な演算子を使用しています。 2番目の形式は単にコマンドを実行し、終了ステータスをテストします。[ expression ]
答え3
needle
変数値から変数値の大文字と小文字を区別する文字列を検索しますhaystack
。
case "$haystack" in
*"$needle"*) echo "present";
*) echo "absent";
esac
大文字と小文字を区別しない文字列検索の場合は、両方とも同じ大文字と小文字に変換してください。
uc_needle=$(printf %s "$needle" | tr '[:lower:]' '[:upper:]' ; echo .); uc_needle=${uc_needle%.}
uc_haystack=$(printf %s "$haystack" | tr '[:lower:]' '[:upper:]' ; echo .); uc_haystack=${uc_haystack%.}
case "$uc_haystack" in
*"$uc_needle"*) echo "present";;
*) echo "absent";;
esac
GNU coreutilsはtr
マルチバイトロケール(UTF-8など)をサポートしていません。マルチバイトロケールを使用するには、代わりにawkを使用してください。 awkを使用している場合は、変換の代わりに文字列比較を実行することができます。
if awk 'BEGIN {exit !index(toupper(ARGV[2]), toupper(ARGV[1]))}' "$needle" "$haystack"; then
echo "present"
else
echo "absent"
fi
BusyBoxはtr
この構文をサポートしません。代わりに使用できます。 BusyBoxはASCII以外のロケールをサポートしません。[:CLASS:]
tr a-z A-Z
bash(shではない)4.0+には、大文字と小文字を変換するための組み込み構文とより単純な文字列一致構文があります。
if [[ "${haystack^^}" = *"${needle^^}"* ]]; then
echo "present"
else
echo "absent"
esac