我在 sed 中测试了单引号和双引号
me@host:~:
$ echo "front" | sed "s/front/back/"
back
me@host:~:
$ echo "front" | sed 's/front/back/'
back
它们的性能相同,但我记得几个月前读到过它们之间存在差异。
Google 搜索对关键字“sed 中的单引号和双引号”没有帮助。
它们并不完全相同,对吗?
答案1
我正在将我之前的评论扩展为答案。
我的建议是坚持使用单引号,除非你知道自己在做什么,并且需要利用某些命令行功能。想到的最常见的情况是文本字符串中的单引号和 shell 变量插值。
以下几个例子充分说明了使用双引号的合理性:
$ echo "We're good!" | sed "s/'re/ are/"
We are good!
$ name="John"; echo "Hello, I'm <name>." | sed "s/<name>/$name/"
Hello, I'm John.
双引号似乎可以实现一些不错的功能,那么为什么不一直使用它们呢?对我来说,主要原因是无法始终看到 实际执行的命令sed
。当命令括在单引号中时,情况非常简单:您看到的就是所sed
看到的。但是,当使用双引号时,您的字符串将在传递给 之前由 shell 进行解释sed
,并且您必须考虑任何修改,其中一些可能不是您想要的。这是一个很好的例子:
$ echo 'SELECT `date` FROM `services`' | sed 's/`date`/`uptime`/'
SELECT `uptime` FROM `services`
如果您使用双引号,那么您的实际sed
命令将是这样的:
$ sed "s/`date`/`uptime`/"
$ sed 's/Wed May 29 08:28:20 UTC 2019/ 08:28:20 up 13 days, 1:29, 1 user, load average: 0.08, 0.02, 0.00/'
在与 连接时,通常可以使用双引号sed
,因为该符号的使用$
往往不含糊:
$ line="back"; echo "front" | sed "s/front$/$line/"
back
$ line="back"; echo "frontline" | sed "s/front$/$line/"
frontline
$ line="-line"; echo "front-line" | sed "s/front$line/back$line/"
back-line
如果您正在编写awk
或perl
,事情会变得更加复杂,其中$
有更多用途:
$ echo "col1 col2 col3" | awk '{print $1}'
col1
$ echo "col1 col2 col3" | awk "{print $1}"
col1 col2 col3
$ echo "col1 col2 col3" | perl -lane 'print $F[0]'
col1
$ echo "col1 col2 col3" | perl -lane "print $F[0]"
ARRAY(0x564346f18db0)
答案2
这实际上与 bash 相关,而不仅仅是命令sed
。
通过查看此示例你可以更好地理解它:
~ $ front="front"
~ $ echo "front" | sed "s/$front/back/"
back
~ $ echo "front" | sed 's/$front/back/'
front
双引号计算其中的表达式,而单引号保留每个字符的字面值。更多信息请见此处:https://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash
答案3
再分享一个例子来说明单引号和双引号造成的不同结果。
当有反斜杠时,单个是不够的,需要\
另一个来转义,即\
\
$ echo "\alpha" | sed 's/\\alpha/\\beta/'
\beta
但对于双引号,我们需要三个引号,
$ echo "\alpha" | sed "s/\\alpha/\\beta/"
\alpha
$ echo "\alpha" | sed "s/\\\alpha/\\\beta/"
\beta
因为\
在 shell 中解释时已经用完了一个。
此外,如果我们想在给定的字符串之前插入,还\
需要一个,
$ echo "\alpha" | sed '/alpha/i \\\beta'
\beta
\alpha
原因我不太清楚,但根据手册,\
命令后面确实有一个i
,
i \
text Insert text, which has each embedded newline preceded by a backslash.
而对于双引号,则需要两个反斜杠,
$ echo "\alpha" | sed "/alpha/i \\\\\beta"
\beta
\alpha