grep apple文件和grep“ apple”文件有什么区别?


22

grep apple file和之间有什么区别grep "apple" file?引号有什么作用?它们看起来都可以工作,并且做的完全一样(显示同一行)。

Answers:


45

引号会影响您的shell认为哪些特殊字符并具有句法含义。在您的示例中,这没有什么区别,因为不apple包含此类字符。

但是考虑另一个示例:grep apple tree fileapple在文件中搜索单词treefile,而grep "apple tree" fileapple tree在文件中搜索单词file。引号告诉bash,其中的单词space "apple tree"不会以新参数开头,而应是当前参数的一部分。grep apple\ tree file会产生相同的结果,因为\告诉bash忽略下一个字符的特殊含义并按字面​​意义对待它。


2
通配符也可见。如果这样做grep a*b equations.txt,它将搜索a*b,除非当前目录中存在一个以a开头并以b结尾的文件,在这种情况下(因为(ba)sh将在命令行上扩展文件名),将使用以下命令调用grep:完成不同的参数,导致不同的结果。这通常是find的问题,因为find . -name *.txt如果当前目录中有txt文件,则类似这样的命令会导致意外的行为。在这种情况下,最好使用引号。
2013年

4
另一个要点是双引号(")和单引号(')之间的区别。单引号禁止解释某些字符,例如$,而双引号允许解释。例如,grep '${USER}'将查找文本${USER},而grep "${USER}"将查找变量USER包含的文本(例如johnstacen)。
帕迪·兰道

23

当在命令行上使用双引号允许评估,单引号阻止评估,无引号允许通配符扩展。作为人为的例子:

[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将某些内容扩展为元素(如数组),则不使用引号;对于不需更改的文字字符串,请使用单引号;对于变量,我可以自由使用双引号可能会返回任何类型的字符串。这是为了确保保留空格和特殊字符。


您将如何在双引号内使用双引号???那是错字吗?为什么我应该在单引号内转义双引号呢?我想你可能把句子混在一起了吗?
字节指挥官

@ByteCommander是的,在双引号中放置双引号的概念是很普遍的- 有关出色的工作示例,请参见本文。通常是为了保护包含空格的字符串,通常是相对于路径字符串而言。可以在带或不带转义的单引号中使用双引号,但是它们将按字面意义进行解释,即它们不会导致求值。我将在帖子中澄清这一点。
AsymLabs 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.