web-dev-qa-db-ja.com

grep Appleファイルとgrep "Apple"ファイルの違いは何ですか?

grep Apple filegrep "Apple" fileの違いは何ですか?引用符を付けるとどうなりますか?どちらも機能しているように見え、まったく同じことを行います(同じ行を表示します)。

22
John Stacen

引用符は、シェルが特殊であるとみなし、構文上の意味を持つ文字に影響を与えます。あなたの例では、Appleにはそのような文字が含まれていないため、これは違いを生じません。

しかし、別の例を考えてみましょう:grep Apple tree fileは、ファイルAppleおよびtreeでWord fileを検索しますが、grep "Apple tree" fileはWord Apple treeを検索しますファイルfileで。引用符は、bashに"Apple tree"内のWordスペースが新しいパラメーターを開始するのではなく、現在のパラメーターの一部となることを示します。 grep Apple\ tree fileは同じ結果を生成します。これは、\がbashに次の文字の特別な意味を無視し、文字どおりに処理するように指示するためです。

45
David Foerster

コマンドラインで使用した場合、二重引用符で評価でき、単一引用符で評価できず、引用符でワイルドカードを展開できません。考案された例として:

[user@work test]$ ls .
A.txt B.txt C.txt D.cpp

# The following is the same as writing echo 'A.txt B.txt C.txt D.cpp'
[user@work test]$ echo *
A.txt B.txt C.txt D.cpp

[user@work test]$ echo "*"
*

[user@work test]$ echo '*'
*

# The following is the same as writing echo 'A.txt B.txt C.txt'
[user@work test]$ echo *.txt
A.txt B.txt C.txt

[user@work test]$ echo "*.txt"
*.txt

[user@work test]$ echo '*.txt'
*.txt

[user@work test]$ myname=is Fred; echo $myname
bash: Fred: command not found

[user@work test]$ myname=is\ Fred; echo $myname
is Fred

[user@work test]$ myname="is Fred"; echo $myname
is Fred

[user@work test]$ myname='is Fred'; echo $myname
is Fred

引用の仕組みを理解することは、Bashを理解する上で極めて重要です。例えば:

# for will operate on each file name separately (like an array), looping 3 times.
[user@work test]$ for f in $(echo *txt); do echo "$f"; done;
A.txt
B.txt
C.txt

# for will see only the string, 'A.txt B.txt C.txt' and loop just once.
[user@work test]$ for f in "$(echo *txt)"; do echo "$f"; done;
A.txt B.txt C.txt

# this just returns the string - it can't be evaluated in single quotes.
[user@work test]$ for f in '$(echo *txt)'; do echo "$f"; done;
$(echo *txt)

単一引用符を使用して、変数を介してコマンドを渡すことができます。単一引用符は評価を妨げます。二重引用符が評価されます。

# This returns three distinct elements, like an array.
[user@work test]$ echo='echo *.txt'; echo $($echo)
A.txt B.txt C.txt

# This returns what looks like three elements, but it is actually a single string.
[user@work test]$ echo='echo *.txt'; echo "$($echo)"
A.txt B.txt C.txt

# This cannot be evaluated, so it returns whatever is between quotes, literally.
[user@work test]$ echo='echo *.txt'; echo '$($echo)'
$($echo)

二重引用符の中に単一引用符を使用でき、二重引用符の中に二重引用符を使用できますが、単一引用符の中に二重引用符を使用できます 行わないでください(エスケープせずに) 評価されず、文字どおりに解釈されます。単一引用符内の単一引用符は(エスケープせずに)実行しないでください。

Bashを効果的に使用するには、引用符を完全に理解する必要があります。非常に重要です!

一般的なルールとして、Bashに何かを要素(配列など)に展開させる場合は引用符を使用せず、変更しないリテラル文字列には単一引用符を使用し、変数には二重引用符を自由に使用しますあらゆるタイプの文字列を返す可能性があります。これは、スペースと特殊文字が確実に保持されるようにするためです。

23
AsymLabs