(嵌套|双|简单)引号的正确用法是什么?

时间:2009-08-11 08:04:16

标签: perl bash shell quotes

我确信这个问题对你们中的一些人来说似乎很愚蠢,但我在这里要学习 这些假设对于大多数语言都是正确的吗? 编辑:好的,我们假设我在谈论Perl / Bash脚本。

'Single quotes'

=>根本没有解释(例如'$'或任何元字符将被视为字符并将在屏幕上打印)

"Double quotes" 

=>变量解释

为了更准确地说明我的问题,我正在编写一些shell脚本(其中引号有时候会很麻烦),并写下这一行:

CODIR=`pwd | sed -e "s/$MODNAME//"`

如果我在我的sed中使用单引号,我的模式将是'$ MODNAME',对吧? (而不是$ MODNAME的实际值,在这种特殊情况下是'alpha')

我遇到的另一个问题是,在回声中有一个awk:

USAGE=`echo -ne "\
Usage : ./\`basename $0\` [-hnvV]\n\
\`ls -l ${MODPATH}/reference/ | awk -F " " '$8 ~ /\w+/{print "> ",$8}'\`"`

我花了一些时间调试那个。我得出结论,反引号被转义,以便解释器不会“拆分”命令(并在«basename»之前停止)。在awk命令中,'$ 8'被awk成功解释,因此不是shell。如果我想使用shell变量怎么办?我会写awk -F“\”$ MY_SHELL_VAR \“”吗?因为$ MY_SHELL_VAR原样,将由awk解释,不是吗?

不要犹豫,添加有关引用或反引号的任何信息!

谢谢! :)

8 个答案:

答案 0 :(得分:7)

它因语言而异。例如,在C / Java / C ++ / C#等系列中,根本不能对字符串使用单引号 - 它们仅用于单个字符。

我认为,对于您真正感兴趣的语言而言,正确地学习规则要好于尝试概括。

答案 1 :(得分:4)

  

这些假设对大多数语言都是正确的吗?

答案:否

答案 2 :(得分:4)

在bash脚本中,backticks are deprecated in favor of $()部分是因为嵌套引号和转义是如何工作的并不明显。您可能还想查看Bash Pitfalls

答案 3 :(得分:2)

对于所有语言来说,它绝对不一样。例如,在Python中,单引号和双引号是可互换的。唯一的区别是你可以在双引号字符串中包含单引号而不转义它们,反之亦然(“怎么样?”)。

此外,还有三引号字符串可以跨越多行。

答案 4 :(得分:2)

在Perl中,你还有q()和qq()来帮助你处理嵌套的引用情况:

my $x = q(a string with 'single quotes');
my $y = qq(an $interpreted string with "double quotes");

这些肯定会帮助你避免“不必要地”“逃避”内部引用。

答案 5 :(得分:1)

是的,awk -F "\"$MY_SHELL_VAR\""之类的东西会起作用,但是在这种情况下你不能在awk中使用变量,因为它们会被shell解释,所以要走的路是这样的(I将使用比你更简单的命令,如果你不介意:)):

awk -F " " '$8 ~ /\w+/{print "> ",$8, '$SOME_SHELL_VAR'}'

请注意单引号终止并重新启动。

最棘手的部分通常是将参数中的引号传递给命令。在这种情况下,您需要终止单引号,添加转义引号字符,再次开始引用,如下所示:

awk '$1 ~ '\''{print}'

请注意,单引号无法在单引号内转义,因为“\”不会被视为转义字符。

这可能与您的静止没有直接关系,但仍然有用。

答案 6 :(得分:1)

我不知道perl,但对于bash,你不需要反斜杠。

至于引号,我有一个(非常个人化的)模式,我称之为“五个引号”模式。将一个引号放在由相同类型的引号括起来的字符串中会有帮助

例如:

doublequoted="some things "'"'"quoted"'"'" and some not"
simplequoted='again '"'"'quote this'"'"' but not that'

请注意,您可以使用不同类型的引号自由附加字符串,这在您希望shell解释某些变量但不解释其他变量时非常有用:

awk -F " " '$8 ~ /\w+/{print "> ",$8, '"$SOME_SHELL_VAR"'}'

另外,我不再使用反引号,而是$(...)模式,它更清晰,可以嵌套。

USAGE=$(echo -ne "
Usage : ./$(basename $0) [-hnvV]\n
$(ls -l ${MODPATH}/reference/ | awk -F " " '$8 ~ /\w+/{print "> ",$8}')")

答案 7 :(得分:1)

在perl中,双引号字符串将扩展其变量。

如果您这样写:

my $email = "foo@bar.com" ;

perl将尝试展开@bar。如果您use strict,您会看到有关阵列栏不存在的抱怨。如果你不这样做,你就会看到一种奇怪的行为。

所以最好写一下:

my $email = 'foo@bar.com' ;

出于这些原因,我的建议是始终对字符串使用单引号,除非您知道需要变量扩展。