在 Ed 中,我可以进行搜索来替换所有空白行,如下所示:
g/^$/d
这将删除所有空白行。但是如果我想删除两个或多个空行并保留 1 个怎么办?例如:
Line 1
Line 2
Line 3
变成:
Line 1
Line 2
Line 3
答案1
改编自Vim 维基:
ed -s file <<EOF
v/./.,/./-1j
w
q
EOF
v/./
:选择所有与正则表达式不匹配的行.
(即选择所有空白行)。对它们执行以下操作:.,/./-1j
:j
oin 命令应用于从选定行 (.
) 到下一个非空行 ( ) 上方的行/./-1
。
w q
: 保存并退出。您可以使用%p Q
它来仅显示输出而不修改文件。
尽管同样有效,但我最初的建议更为复杂:
printf '%s\n' 'g/^$/.,/./-1d\' 'i\' '' w q | ed -s file
这个命令使用两个命令来表示单个g
全局命令(通常命令列表由单个命令组成),这需要在其命令列表中为其换行符添加反斜杠前缀。
g/^$/
:选择所有空白行。.,/./-1d\
:d
从所选行 (.
) 删除到下一个非空行 ( ) 上方的行/./-1
。这将删除所有空白行,所以'i\' ''
:i
在上面插入一个新的空行。
相当于使用此处文档或 Printf 来馈送 Ed。只需选择您最喜欢的一个即可。
参考:POSIX 版。
答案2
使用外部命令是一种完全有效的编辑方式ed
,并且假设所有非空行与其周围的行(即非重复)相比都是唯一的,我们可以调用uniq
删除多余的空行:
w
e !uniq %
我们需要w
先保存我们的工作,因为uniq
将从磁盘上的当前文件中读取。该e !somecommand
命令将编辑缓冲区的内容替换为 的输出somecommand
,并将uniq
删除指定文件中重复的连续行。命令中的%
将会替换为当前文件的名称。根据我们一开始的假设,这通过删除重复的连续空行解决了我们的问题。