シェルスクリプトで大文字と小文字を区別しない部分文字列の検索

シェルスクリプトで大文字と小文字を区別しない部分文字列の検索

コマンド出力で大文字と小文字を区別しない部分文字列一致を実行するシェルスクリプトをどのように記述できますか?

答え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 worksecho 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

関連情報