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


22

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


grep -i多分?
ラメシュ

スクリプト内にどのように配置しますか?これが初心者の質問であればごめんなさい。インターンシップに必要なため、Linuxの勉強を始めたばかりです。ありがとう!
ミゲルロケ

1
あなたが求めているのはシェルスクリプトです。「linux」はプログラミング言語ではなく、オペレーティングシステムのカーネルです。Linuxで最も一般的に使用されるシェルbashは、UNIX標準のshスーパーセットです。次のいずれかを見ることから始めるかもしれません:| 1 | | 2 | -単に実際のコンテキストが何であるかを把握するためです。
goldilocks

1
この質問は非常に明確になり、ヘルプセンターのガイドラインと一致しています。他の人のために開いてください。
BobDoolittle

2
この質問が明確でない理由はわかりません。明確にするために何を追加する必要がありますか?
ミゲルロケ14年

回答:


11

最初に、大文字小文字を無視しない簡単なスクリプト例を示します。

#!/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は、一致が見つかった場合にのみ成功して終了します。

-igrep のオプションは、大文字と小文字を区別しないことを示しています。
この-qオプションは、出力を出力せず、最初の一致後に終了することを示しています。オプションは、文字列ではなく、正規表現として引数を処理するために述べています。
-F

最初の例では、直接比較とさまざまな便利な演算子を使用できることに注意してください。2番目の形式は、単にコマンドを実行し、終了ステータスをテストします。[ expression ]


貢献したコードを変更する必要があるとGillesが感じた理由がわかりません。彼は何も壊さなかったが、それはうまく機能した。この例では二重引用符は必要ありません-ただし、出力にスペースが含まれている場合、二重引用符は重要です。そして、==は、=と同様に機能します。なぜなら、shは実際にはLinuxでbashであるからです。元のボーンシェルは、この時点で長い間なくなりました。Solarisでさえ、もう出荷しないと思います。この例では不要ですが、二重引用符がおそらくベストプラクティスであることに同意しますが、割り当てと比較を明確に区別するために、私の意見では '=='もそうです。
BobDoolittle

待って、投稿を編集できますか?私は知りませんでした。
ミゲルロケ

十分な評判で、はい。ただし、特にこのフォーラムのコードについては、不評の編集を行う前に、評判の高い人が考え直してくれることを願っています。unix.stackexchange.com/help/privileges
BobDoolittle

@BobDoolittle 場合によっては違いがありますが、セットアップには違いがあります。知っておくと良いでしょう。

2
実際には、Bourneシェルだけではないことに注意してください。==POSIXではありません。すべてのLinuxベースのシステムでshはありませんbash。(少なくとも多くのBSDおよびDebian派生物のベースとなっている)、またはで==サポートされていないため、で引用する必要があります。を倍にする意味はありません。テスト用のコマンドです。ここでは、割り当てと比較を明確にする必要はありません。それはで違う対。で始まるスクリプトでの使用は間違っています。または仮定する場合は、それに応じて更新します。ashshposhzsh=[(( a == b ))(( a = b))==#! /bin/shkshbash#!
ステファンシャゼル

49

シェルオプションを設定すると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

6
笑!不明瞭なシェルの知識のポイント。
BobDoolittle

2
このオプションは、単純一致演算子にも影響します。[[ XYZ == xyz ]] && echo "match"=>match
itsadok

7

変数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

trGNU 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

trBusyBoxのからはサポートされていない構文を。代わりに使用できます。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除いて。
ウィル

@Willそれは<<<演算子があるシェルでのみ機能します:ksh、bash、zsh、しかし普通のshではありません。そして、printf実行方法の観点からは、ほぼパイピングに近い:と同じ数の呼び出しがforkありますexecveprintf組み込みであると仮定します。これは、ほとんどの一般的なシェルに当てはまります)。違いは<<<、パイプを使用するのではなく一時ファイルを作成することです。<<<入力は便利ですが、パフォーマンスは向上しません。
ジル 'SO-悪であるのをやめる'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.