コマンド出力の大文字と小文字を区別しない部分文字列一致を行うシェルスクリプトを作成するにはどうすればよいですか?
bash
は、UNIX標準のsh
スーパーセットです。次のいずれかを見ることから始めるかもしれません:| 1 | | 2 | -単に実際のコンテキストが何であるかを把握するためです。
コマンド出力の大文字と小文字を区別しない部分文字列一致を行うシェルスクリプトを作成するにはどうすればよいですか?
bash
は、UNIX標準のsh
スーパーセットです。次のいずれかを見ることから始めるかもしれません:| 1 | | 2 | -単に実際のコンテキストが何であるかを把握するためです。
回答:
最初に、大文字小文字を無視しない簡単なスクリプト例を示します。
#!/bin/bash
if [ $(echo hello) == hello ]; then
echo it works
fi
右側の文字列helloを変更してみてくださいit works
。エコーは発生しなくなります。echo hello
選択したコマンドに置き換えてみてください。大文字と小文字を区別せず、どちらの文字列にも改行が含まれていない場合は、grepを使用できます。
#!/bin/bash
if echo Hello | grep -iqF hello; then
echo it works
fi
ここで重要なのは、コマンド出力をにパイプすることですgrep
。このif
ステートメントは、パイプラインの右端のコマンド(この場合はgrep)の終了ステータスをテストします。Grepは、一致が見つかった場合にのみ成功して終了します。
-i
grep のオプションは、大文字と小文字を区別しないことを示しています。
この-q
オプションは、出力を出力せず、最初の一致後に終了することを示しています。オプションは、文字列ではなく、正規表現として引数を処理するために述べています。-F
最初の例では、直接比較とさまざまな便利な演算子を使用できることに注意してください。2番目の形式は、単にコマンドを実行し、終了ステータスをテストします。[ expression ]
==
POSIXではありません。すべてのLinuxベースのシステムでsh
はありませんbash
。(少なくとも多くのBSDおよびDebian派生物のベースとなっている)、またはで==
サポートされていないため、で引用する必要があります。を倍にする意味はありません。テスト用のコマンドです。ここでは、割り当てと比較を明確にする必要はありません。それはで違う対。で始まるスクリプトでの使用は間違っています。または仮定する場合は、それに応じて更新します。ash
sh
posh
zsh
=
[
(( a == b ))
(( a = b))
==
#! /bin/sh
ksh
bash
#!
シェルオプションを設定すると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
[[ XYZ == xyz ]] && echo "match"
=>match
変数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
tr
GNU coreutilsではマルチバイトロケール(UTF-8など)をサポートしていないことに注意してください。マルチバイトロケールで動作させるには、代わりにawkを使用します。awkを使用する場合は、変換だけでなく文字列の比較を行うことができます。
if awk 'BEGIN {exit !index(toupper(ARGV[2]), toupper(ARGV[1]))}' "$needle" "$haystack"; then
echo "present"
else
echo "absent"
fi
tr
BusyBoxのからはサポートされていない構文を。代わりに使用できます。BusyBoxは非ASCIIロケールをサポートしていません。[:CLASS:]
tr a-z A-Z
bash(shではなく)バージョン4.0+には、大文字小文字変換のための組み込み構文と、文字列マッチングのためのより単純な構文があります。
if [[ "${haystack^^}" = *"${needle^^}"* ]]; then
echo "present"
else
echo "absent"
esac
printf | tr
が、それだけで頭がぐるぐる回っています。可能な場合は、コマンドの呼び出しを最小限に抑えます...変数vを指定すると、を使用して同じことを実現できますv=$(tr '[:lower:]' '[:upper:]' <<<$v)
。これまで見たことのない人にとって、<<<
は<<EOF
、here文書の使用のように、本質的に「here変数」です。絶対にそうしなければならないprintf
場合をecho
除いて。
<<<
演算子があるシェルでのみ機能します:ksh、bash、zsh、しかし普通のshではありません。そして、printf
実行方法の観点からは、ほぼパイピングに近い:と同じ数の呼び出しがfork
ありますexecve
(printf
組み込みであると仮定します。これは、ほとんどの一般的なシェルに当てはまります)。違いは<<<
、パイプを使用するのではなく一時ファイルを作成することです。<<<
入力は便利ですが、パフォーマンスは向上しません。
grep -i
多分?