grepで一重引用符、二重引用符を使用する場合


20

ファイル内の単純なパターン「hello」を検索しようとすると、次のすべての形式のgrepが機能します。

  • grep hello file1
  • grep 'hello' file1
  • grep "hello" file1

上記のフォームのいずれかが機能し、他のフォームが機能しない特定のケースがあります。別の場所で使用すると違いがありますか?

回答:


25

これは実際にはシェルに依存しています。引用符(どちらの種類でも)は、主に空白を扱うことを目的としています。たとえば、次のとおりです。

grep hello world file1

「world」および「file1」というファイルで「hello」という単語を探しますが、

grep "hello world" file1

file1で「hello world」を探します。

一重引用符または二重引用符の間の選択は、検索文字列に変数または評価される予定の他のアイテムが含まれている場合にのみ重要です。単一引用符を使用すると、文字列は文字どおりに取得され、展開は行われません。二重引用符を使用すると、変数が展開されます。例(BashやZSHなどのBourne派生シェルを使用):

VAR="serverfault"
grep '$VAR' file1
grep "$VAR" file1

最初grepは、file1でリテラル文字列「$ VAR1」を探します。2番目は「$ VAR」変数を展開し、file1でストリング「serverfault」を探します。


注意すべき重要なことは、元の質問では、grepは実際には毎回まったく同じ引数を受け取っているということです。
MikeyB

2
そこに注意してください。 $は正規表現の行末なので、$VAR1実際に何にも一致することはありません。それはたまたまGNU grepで動作しますが、私はまだその動作を期待していません。\$VAR1リテラル文字列を安全に一致させる必要があります。(つまり、二重引用符でいた場合そして、あなたは余分なバックスラッシュを必要とするだろう。)
スティーブン・プリチャード

7

ジェームズは正しいですが、さらにデータを追加するには、コマンドの引数として考えるのが最善の方法だと思います。引数。

また、二重引用符を使用すると、単なる変数以上の解釈が可能になります。シェルによって異なりますが、履歴展開、ブレース展開、およびファイル名展開を確認してください。

また、単一の引数で両方のタイプの引用符を使用する必要がある場合があることに注意することも重要です。(デフォルトでは)引数は空白で区切られているため、スペースを残さない場合でも、同じ引数を指定していることに注意してください。

ほとんどのシェルのシングルクォートメカニズムでは、特殊文字は使用できません。つまり、別のシングルクォートのインスタンスは、エスケープされているように見えても、クォートを終了します。したがって、単一引用符で囲まれた文字列内に単一引用符で文字列を渡すことは不可能であり、二重引用符を使用する必要があります。これは、一重引用符と解釈される何かを含む引数を渡したいが、そうしたくない場合に苦痛になる可能性があります。たとえば、リテラル文字列「 `'$ VAR'は変数です」を渡したい場合は、次のように行う必要があります。

"'"'$VAR'"' is a variable"

これは、実際には3つの引用符でエスケープされた文字列の連結です。

"'"
'$VAR'
"' is a variable"

または、引用符を削除して:

'
$VAR
' is a variable

実際、ほとんどのシェルでは、次の方法でも実行できます。

"'\$VAR' is a variable"

ここで、バックスラッシュ( " \")は、シェルに次の文字をそのまま受け入れ、展開を行わないように指示します。

しかし、いくつかの場合には、複数の文字列を連結する方法で行う必要がありますが、今すぐ実際に例を挙げることはできません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.