一重引用符を使用するときにgrepが期待した結果を返さないのはなぜですか?

一重引用符を使用するときにgrepが期待した結果を返さないのはなぜですか?

次の内容を含むファイルがあります。

sh-4.2$ cat file1
example of multiple
pattern
this is an
example of multipole
sorry multiple
pattern matching
using grep
so the example is the
file itself
-example
-multiple
-bye
tata
!

上記のファイルから "-example"を検索すると、grepコマンドは目的の出力を提供しません。パターンに「-」が含まれている場合は、-eオプションを使用する必要があることがわかります。

私が使用した最初の例では、-はい引用符なしで直接:

sh-4.2$ grep -example file1
example of multiple
example of multipole
so the example is the
-example

-はい一重引用符を使用する:

sh-4.2$ grep '-example' file1
example of multiple
example of multipole
so the example is the
-example

-はい二重引用符とエスケープ文字を含む

sh-4.2$ grep "\-example" file1
-example
sh-4.2$

答え1

検索パターンに「-」が含まれており、検索パターンに「-」が含まれている場合は、その-eフラグを使用する必要があります。そのフラグを使用しないため、-eシェルは「パターン」を引数(およびパラメータ)として解釈します。以下で見ることができます:

$ grep "-foo" file1
grep: oo: No such file or directory

拡張すると、コードは引数と「xample」引数を使用して実行するgrep "-example" file1シェルを示します。grep-e

これは、同様のアプローチを試みたときに経験したのと同じ問題です。rm -my-silly-file-nameうまくいかなかったので、同様のアプローチを使用する必要がありますrm ./-my-silly-file-name。別の解決策はrm -- -my-silly-file-name次のとおりです。

$ grep -- "-example" < file1
-example

「--」は、シェルに続くすべてを伝えます。いいえ議論。

または、次のように「\」を使用して「-」をエスケープすることもできます。

grep "\-example" file1

この記事では、参照の詳細の一部を詳しく説明します。:関連部分はシェルで解釈する必要があるパラメータと逆引用符コマンドは二重引用符で囲みます。二重引用符を使用すると、内容はシェルで解釈されます。

答え2

「'-'で始まるパターンは-eオプションを使用する必要があることを知っていますが、使用する必要があるときは使用していません。grep -e -example file1期待した結果が得られます。

各例で実際に実行されるタスクは次のとおりです。

  • grep -example file1=> grep -e xample file1(-eが必要です)
  • grep '-example' file1=> grep -e xample file1(-eが必要です)
  • grep "\-example" file1=> grep \-example file1(-eは必須ではありません)

答え3

で始まる引数は-オプションと見なされます。

最初の2つのケースで渡された最初の引数は、解釈される引数grepです(options、したがってsearch)。-examplegrep-e xamplexample-example

3番目のケースでは、で始まらないので、\-exampleに渡されます。正規表現として扱われます。ただし、動作はPOSIXの下に指定されていないため、一致する内容を保証することはできません。ほとんどの実装では、aは一致しますが特殊演算子である可能性がある実装を想像できます(たとえば、aは特殊演算子であり、リテラルと一致しないGNUを参照)。grep-\-grep\--grep\-grep\++

-exampleオプションと見なされないようにするには、次のことを行う必要があります。

  • grep -- -example file--オプションの終わりを表示します。それ以降のすべてはオプションではありません(したがって、最初の引数は検索するパターンで、残りは検索するファイルのリストです)。
  • grep -e -example file。ここでパラメータはオプション-exampleとして扱われます-e

執筆に慣れるべき理由は次のとおりです。

grep -e "$pattern" file

または

grep -- "$pattern" file

保証できない場合は$pattern開始されません-

ここに次のように書くこともできます。

grep '[-]example' file

見たけど範囲のない角括弧式は、bashの予期しない文字と一致します。このアプローチの可能な合併症について。

関連情報