如何删除从第5行开始的空行

如何删除从第5行开始的空行

我有这个:

sed -i '/^$/d' temp_spec.rb

这是剥离空白行并且效果很好。我怎样才能让它只对第 5-999 行(或者最好是第 5 行到文件末尾)执行此操作。

我试过:

sed -n5,999 -i '/^$/d' temp_spec.rb
sed '5,999!d/^$/d' temp_spec.rb

但都不起作用(没有错误)。

答案1

如果要删除从第5行开始的所有空白行并保留第1行到第4行,可以使用

sed -i '5,${;/^$/d;}' temp_spec.rb

{分组运算符,所以第一条命令的5,${意思是“从第5行到input( $)结束执行以下命令,直到匹配}”。{和之间的命令}也可以用地址作为前缀,因此内部命令的意思是“如果该行的开头 ( ) 和结尾 ( )/^$/d之间没有任何内容,则删除它”。 sed 命令可以用 分隔。 (这是 sed 的一个记录很差的功能。大多数 sed 实现都支持它,但它是^$;不完全便携.) 正如 Hauke 所指出的,;后面的内容{是可选的;不过,前面的那个}是必需的。

如果要删除从第 5 行开始的所有空白行,并删除第 1 至 4 行,则更容易:

sed -i '1,4d;/^$/d' temp_spec.rb

答案2

使用 awk 的另一个选项:

awk 'NR<5||/./'

答案3

sed '5,${s/^$//; t delete; b end; : delete; d; : end;}' temp_spec.rb

编辑1:

我应该解释一下这一点,因此......

这不必要地复杂。我不知道{}.所以我必须以不同的方式表达“删除空行”。核心命令是twhich 是 sed 的方式if ... thenT本来会更容易,但仅适用于 GNU sed。我引用手册页:

t label :如果自上次读取输入行以来以及自上次 t 或 T 命令以来 as/// 已成功替换,则分支到 label;如果省略标签,则分支到脚本末尾。

我滥用了著名的s命令。它不会替换任何内容,而仅测试该行是否为空。因此,它用空行替换空行(可以使用任何内容作为替换,因为无论如何该行都会被删除)。

如果s已完成“替换”,则该行为空。在这种情况下,d应执行该命令。否则什么也不能做。由于t在执行操作时不会跳转,s我需要分支命令b跳转到脚本的末尾。: label是分支目标。就像goto在黑暗时代那样(当 sed 被发明时...... te-hee)。

另一种选择是s“替换”所有非空行,使s命令更复杂,但其余部分更容易:

sed '5,${s/^\(..*\)$/\1/; t end; d; : end;}' input

^..*$表示“非空行”,\1表示“第一个括号的内容”。

相关内容