“sed -e”和用分号分隔多个命令之间的区别

“sed -e”和用分号分隔多个命令之间的区别

我也许在这里挑剔,但如果这个一直困扰我的问题得到一劳永逸的答案,那就太好了......

代表的文本文件:

Line one.
Line two.

Line three.
Line four.

sed要一致地向此文本文件添加额外的空行,每行需要两个命令。这可以通过以下任何语法来实现:

  1. sed -e '/^$/d' -e '$!G' <file>...但不是(sed -e '/^$/d' '$!G' <file>sed '/^$/d' '$!G' <file>
  2. sed -e '/^$/d; $!G' <file>或者sed -e '/^$/d ; $!G' <file>
  3. sed '/^$/d; $!G' <file>或者sed '/^$/d ; $!G' <file>

我的问题是:

  1. 上面列出的五种工作语法之间是否有任何真正的区别(通用性?,合规性?...)?
  2. 理查德·布鲁姆的最新作品命令行和 Shell 脚本圣经sed -e 's/brown/red/; s/dog/cat/' data1.txt说在给出以下建议之前使用类似的东西......

命令必须用分号 (;) 分隔,并且第一个命令末尾和分号之间不应有任何空格。

...然后继续完全忽略他自己的建议,-e根本不使用该选项,并在命令末尾和分号之间添加空格(如上面 #3 的第二个变体所示).. 所以,分号周围的间距有什么真正的区别吗

  1. 尽管我在联机帮助页或文档中找不到有关此内容的信息,但我的预感是该-e选项应该按照上面的语法#1 中所示的方式使用,并且在命令行上同时使用 和 是多余的-e;我对么?

编辑:我应该在原来的问题中提到这一点以使其更具体;但正如有些人已经指出的那样,在使用branch( b)或test( t)命令时,这些细微差别很重要。但有趣的是,注意其他情况,这些情况会产生影响。谢谢!

答案1

这对于一些命令来说确实很重要。

在原始sed实现中,: foo;bar、分别定义、b foo;bar分支t foo;bar、条件分支到foo;bar标签。

它甚至曾经是 POSIX 所要求的(我是那个要求放宽要求)。

w foo;bar并且仍然在所有符合要求的实现中向文件r foo;bar写入/从文件读取。foo;bar

命令#(用于注释)、aic(追加、插入、更改)显然不能在同一行上跟另一个命令。

历史sed实现也不支持}后面跟着另一个命令。

POSIX 曾经说过你不能有一个;before },尽管在实践中不需要(我也要求放宽这一要求)。

sed -e cmd1 -e cmd2

意味着相当于

sed -e 'cmd1
cmd2'

但实际上,并非所有实现都如此:

sed -e 'a\' -e 'foo\' -e 'bar'
sed -e 's/foo/bar\' -e 'baz/g'

例如。

答案2

让我们使用Sed POSIX 标准回答问题。

分号周围的间距有什么真正的区别吗?

除 {...}、a、b、c、i、r、t、w、: 和 # 之外的编辑命令后面可以跟一个分号、可选的空白字符和另一个编辑命令。

因此/^$/d ; $!G不符合要求,但/^$/d; $!G确实符合要求。但我确实想知道是否有任何现代 Sed 实现会偶然发现这一点。

上面列出的三种语法之间是否有任何真正的区别(通用性、合规性......)?

否(如上所述,分号前有空格的除外)。这一点在概要中说得很清楚:

sed [-n] script [file...]  
sed [-n] -e script [-e script]... [-f script_file]... [file...]

但请注意,正如前面提到的,有些命令后面不能跟分号,然后

sed -e ':a' -e 's/x/y/' -e 't a'

是合规的,同时

sed ':a;s/x/y;t a'

虽然不是,但至少在 GNU Sed 中工作是一样的。

我的预感是,(...)在命令行上同时使用-e和是多余的。;我对么?

如果您参考问题中的示例,是的。如果只有一个-e 选项,那么只需将其删除即可,一切都是一样的(除非您也使用该 -f选项(请参阅概要))。但在

sed -e ':a' -e 's/x/y;t a'

和都存在-e;但它们并不多余。

答案3

好处似乎是编辑命令。

sed -e '/first/a This is cool' -e '/second/i also cool' < <(echo first; echo second)

将产生:

first
This is cool
also cool
second

但正在尝试

sed -e '/first/a This is cool ; /second/i also cool' < <(echo first; echo second)

产量

first
This is cool ; /second/i also cool
second

显然将分号解释为附加的一部分。尽管您仍然可以通过单个命令来实现此目的:

sed -e '/first/a This is cool
/second/i also cool' < <(echo first; echo second)

利用硬返回来启动新命令(允许脚本文件正确运行)。

诚然:

sed '
/first/a This is cool
/second/i also cool' < <(echo first; echo second)

相关内容