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:
我应该解释一下,因此...
这不必要地复杂。我不知道内的地址范围是允许的{}。因此,我不得不用不同的方式表达“删除空白行”。核心命令是tsed的方式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表示“第一个括号的内容”。