Answers:
如果要删除从第5行开始的所有空白行,并保留第1至4行,则可以使用
sed -i '5,${;/^$/d;}' temp_spec.rb
由于{
是分组运算符,因此第一个命令的5,${
意思是“从第5行到输入($
)的末尾执行以下命令,直到匹配}
”。{
和之间的命令}
可以再次加上地址前缀,因此内部命令的/^$/d
意思是“如果该行的开始(^
)和结束($
)之间没有任何内容,则将其删除”。sed命令可以用分隔;
。(这是sed的一个文献记录不清的功能。大多数sed实现都支持此功能,但它并不是完全可移植的。)正如Hauke所指出的,;
after {
是可选的;不过,这}
是必需的。
如果要删除从第5行开始的所有空白行,并且还删除第1至4行,则比较容易:
sed -i '1,4d;/^$/d' temp_spec.rb
;
。
;
。
sed '5,${s/^$//; t delete; b end; : delete; d; : end;}' temp_spec.rb
编辑1:
我应该解释一下,因此...
这不必要地复杂。我不知道内的地址范围是允许的{}
。因此,我不得不用不同的方式表达“删除空白行”。核心命令是t
sed的方式if ... then
。T
本来会更容易,但仅适用于GNU sed。我引用了手册页:
t label:如果自从最后一条输入行被读取以来以及从最后一个t或T命令以来,as ///已成功完成替换,则跳转到label;如果省略了label,则跳转到脚本结尾。
我滥用了著名的s
命令。它不能替代任何东西,而只能测试行是否为空。因此,它将用空行替换空行(无论如何删除行都可以使用任何东西作为替换)。
如果执行s
了“替换”,则该行为空。在这种情况下,d
应执行命令。否则,什么都不做。因为在t
执行操作时不会跳转,所以s
我需要使用branch命令b
跳转到脚本的末尾。: label
是分支目标。就像goto
在黑暗时代(当sed发明时…te-hee)一样。
另一种选择是s
“替换”所有非空行,使s
更复杂但其余部分的命令更容易:
sed '5,${s/^\(..*\)$/\1/; t end; d; : end;}' input
^..*$
表示“非空行”,\1
表示“第一个括号的内容”。