我可能是在这里挑毛病,但是让这个一直困扰我的问题一劳永逸地回答真是太好了......
reprex 的文本文件:
Line one.
Line two.
Line three.
Line four.
Run Code Online (Sandbox Code Playgroud)
要始终向该文本文件添加额外的空行sed,每行需要两个命令。这可以通过以下任何一种语法来实现:
sed -e '/^$/d' -e '$!G' <file>...但不是(sed -e '/^$/d' '$!G' <file>或sed '/^$/d' '$!G' <file>)sed -e '/^$/d; $!G' <file> 或者 sed -e '/^$/d ; $!G' <file>sed '/^$/d; $!G' <file> 或者 sed '/^$/d ; $!G' <file>我的问题是:
sed -e 's/brown/red/; s/dog/cat/' data1.txt在提出以下建议之前要使用类似的东西......命令必须用分号 (;) 分隔,并且第一个命令的末尾和分号之间不应有任何空格。
...然后继续完全忽略他自己的建议,根本不使用该-e选项,还在命令末尾和分号之间添加空格(如上面#3 的第二个变体所示)。所以,分号周围的间距有什么真正的区别吗?
-e选项的使用方式如上面的语法编号 #1 所示,并且在命令行上同时使用-e和;是多余的。我对么?编辑:我应该在我原来的问题中提到这一点,以使其更具体;但正如一些人已经指出的那样,在使用 branch ( b) 或 test ( t) 命令时,这些细微差别会很重要。但有趣的是要注意其他情况,当这些情况会有所不同时。谢谢!
让我们使用Sed POSIX 标准来回答这些问题。
分号周围的间距有什么真正的区别吗?
除了 {...}、a、b、c、i、r、t、w、: 和 # 之外的编辑命令可以跟一个分号、可选的空白字符和另一个编辑命令。
因此/^$/d ; $!G不合规,但合规/^$/d; $!G。但我确实想知道是否有任何现代 Sed 实现会偶然发现。
上面列出的三种语法中的任何一种之间是否有任何真正的区别(通用性、合规性...)?
否(分号前有空格的除外,如上所述)。这在概要中很清楚:
Run Code Online (Sandbox Code Playgroud)sed [-n] script [file...] sed [-n] -e script [-e script]... [-f script_file]... [file...]
但是,请注意,正如前面提到的,某些命令后面不能跟分号,然后
sed -e ':a' -e 's/x/y/' -e 't a'
Run Code Online (Sandbox Code Playgroud)
是合规的,而
sed ':a;s/x/y;t a'
Run Code Online (Sandbox Code Playgroud)
不是,但至少在 GNU Sed 中工作相同。
我的预感是 (...)在命令行上同时使用-e和;是多余的。我对么?
如果您参考问题中的示例,是的。如果只有一个-e
选项,则只需删除它,它都是一样的(除非您也使用该
-f选项(请参阅概要))。但在
sed -e ':a' -e 's/x/y;t a'
Run Code Online (Sandbox Code Playgroud)
双方-e并;都存在,但它们不是多余的。
它对一些命令很重要。
在原始sed实现中: foo;bar,b foo;bar、t foo;bar分别定义了分支、条件分支到foo;bar标签。
它甚至曾经是 POSIX 所要求的(我是要求放宽要求的人)。
w foo;bar并且r foo;bar仍然foo;bar在所有符合要求的实现中写入/读取文件。
该#命令(征求意见)a,i,c(追加,插入,修改)显然不能跟着在同一行另一个命令。
历史sed实现也不支持}后跟另一个命令。
POSIX 过去常说你不能有一个;,}尽管在实践中不需要(我也要求放宽这个要求)。
sed -e cmd1 -e cmd2
Run Code Online (Sandbox Code Playgroud)
意味着等价于
sed -e 'cmd1
cmd2'
Run Code Online (Sandbox Code Playgroud)
但实际上,在所有实现中,情况并非如此:
sed -e 'a\' -e 'foo\' -e 'bar'
sed -e 's/foo/bar\' -e 'baz/g'
Run Code Online (Sandbox Code Playgroud)
例如。