:a; $!N;是什么意思 在sed命令中?


11
$ (echo hello; echo there) | sed ':a;$!N;s/\n/string/;ta'
hellostringthere

上面的sed命令用字符串“ string”替换换行符。但是我不知道:a;$!N;s/\n/string/;ta单引号内的含义。我知道中间部分s/\n/string/。但是我不知道first(:a;$!N;)和last(ta)部分的功能。



那最后一部分呢?
Avinash Raj 2014年

如果最后一个替代命令修改了模式空间,则“ t”命令将分支到命名标签。
xiaodongjie 2014年

Answers:


17

这些是公认的神秘sed命令。具体而言(来自man sed):

:label
         b和t命令的标签。

t label
         如果as ///自从最后一条输入行被读取以来以及从最后的t或T命令以来已成功完成替换,则跳转到label;如果省略了label,则跳转到脚本结尾。

n N将下一行输入读/追加到模式空间。

因此,您发布的脚本可以分解为(为便于阅读而添加的空格):

sed ':a;  $!N;  s/\n/string/;  ta'
     ---  ----  -------------  --
      |     |        |          |--> go back (`t`) to `a`
      |     |        |-------------> substitute newlines with `string`
      |     |----------------------> If this is not the last line (`$!`), append the 
      |                              next line to the pattern space.
      |----------------------------> Create the label `a`.

基本上,这可以用伪代码编写为

while (not end of line){
    append current line to this one and replace \n with 'string'
}

通过更复杂的输入示例,您可以更好地理解这一点:

$ printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;$!N;s/\n/string/;ta'
line1stringline2stringline3stringline4stringline5

我不太确定为什么!$需要它。据我所知,您可以获得与

printf "line1\nline2\nline3\nline4\nline5\n" | sed ':a;N;s/\n/string/;ta'

1
!$与最后一个换行符IMO不匹配。
Braiam 2014年

@Braiam对此不太确定,$!不是!$。但是,也可能!N不是$!
terdon

我试图解析texinfo页面,但没有找到对!N或的引用$!。因此,我仍然保持我的想法,那就是在寻找最后一行是换行符还是EOF。
Braiam 2014年

4
我尝试将其$!视为带有后缀补码运算符的地址“范围”-因此$!NN除address之外的所有操作$)实际上与诸如m,n!d(删除mto 以外的所有内容n)的语法相同。
钢铁司机

:goto标签的类似物,实际上:曾经是Thompson外壳中的goto标签,因此人们在白天同时使用sed和Thompson外壳会很熟悉
Sergiy Kolodyazhnyy

0

我发布这个答案,因为我看到一个关于很多困惑,为什么在执行时的最后一行被排除N(通过行写入字符串$!),并因为OP感到困惑的含义:a;$!N; 一个 sed命令,不仅特定的一个,他发布。

好吧,在提议的示例中(由OP和@terdon使用),使用$!N代替代替的好处N并不明显,因为在N命令后的最后一行没有执行“重要”(保持读取)命令。(实际上,如果剥离该行地址,结果是相同的。)

在一个更复杂的示例中(例如,替换this sentence为一个文件,两个单词有时出现在一行中,而另一些时候则出现在两行中),排除N命令的最后一行可能至关重要!如果最后一行不排除,一旦执行N就可以了,sed撞击EOF和出口立即,防止所有的后续命令(分支指令为好,即tb将被执行)。

在所示的过于简单的示例中,我们可以安全地删除$!并让sed执行失败N并返回失败,因为中止的s命令如果执行则不会执行任何操作,因为没有\n匹配项。

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.