我知道
cat foo | sed '$!N;$!D'
将打印出文件 foo 的最后两行,但我不明白为什么。
我已经阅读了手册页并且知道N加入了当前处理线的下一行等等 - 但是有人可以用“良好的英语”来解释这里的操作顺序是一步一步的吗?
谢谢!
答案 0 :(得分:4)
这是通过sedsed
调试器运行时脚本的样子(Aurelio Jargas):
$ echo -e 'a\nb\nc\nd' | sed '$!N;$!D' PATT:^a$
PATT:^a$
COMM:$ !N
PATT:^a\Nb$
COMM:$ !D
PATT:^b$
COMM:$ !N
PATT:^b\Nc$
COMM:$ !D
PATT:^c$
COMM:$ !N
PATT:^c\Nd$
COMM:$ !D
PATT:^c\Nd$
c
d
我已经过滤掉了显示保留空间(“HOLD”)的行,因为它没有被使用。 “PATT”显示模式空间中的内容,“COMM”显示即将执行的命令。 “\ N”表示嵌入的换行符。当然,“^”和“$”表示字符串的开头和结尾。
!N
附加下一行,!D
删除前一行并循环到脚本的开头而不进行隐式打印。当读取最后一行时,$!
测试失败,因此没有什么可做的,脚本退出并执行模式空间中剩余内容的隐式打印(因为参数中未指定-n
)。
免责声明:我是sedsed
项目的贡献者,并做了一些小改进,包括扩展色彩支持,添加^
行开头指标和Python 3的初步支持。版本(最近没有被触及)是here。
答案 1 :(得分:1)
$!N;$!D
是一个sed
计划,由两个语句$!N
和$!D
组成。
$!N
匹配输入的最后一行文件的最后一行($
被!
否定)并在其上运行N
命令,正如您所说你自己将下一行输入附加到当前正在审查的行(“模式空间”)。换句话说,sed
现在在模式空间中有两行,并且已经前进到下一行。
$!D
也匹配除最后一行之外的所有内容,并将模式空间擦除到第一个换行符。 D
还会阻止sed
在读取下一行时擦除整个模式空间。
因此,正在执行的算法大致是:
For every line up to but not including the last {
Read the next line and append it to the pattern space
If still not at the last line
Delete the first line in the pattern space
}
Print the pattern space