2

它一直困扰着我,sed没有j命令,就像ed没有命令一样。

这个问题一般询问如何连接线,并且有很多很好的答案,其中许多具有其他工具,例如awkperl。也有一些sed解决方案,但它们都涉及使用s命令从字面上编辑换行符,这是一种解决方案,由于各种原因让我觉得很笨拙。

现在,sed还有一些与“保持”和“模式”空格有关的晦涩命令,我从来没有弄清楚如何使用。我一直假设 - BICBW - 保留空间是 sed 对j命令的回答,只要我能弄清楚如何使用它。

所以我今天的问题——这既是一个知识分子问题,也是一个实际问题——是,有没有一种好的、安全、合理简洁的方法来做相当于

sed /pat/j

也就是说,对于包含 pattern 的每一行pat,将其连接到下一行(也就是说,就像ed我使用一样g/pat/j/)。

正如我所说,这在某种程度上是一个智力问题。我知道如何使用其他工具连接行,或者通过在引用的文字换行符上使用sed和命令。s但在我看来,应该有更好的方法。

(或者也许我应该只获取一份副本sed.c并输入正确的j命令。)

4

2 回答 2

3
sed  '/pat/{$!{N;s/\n/ /}}'

如果pat匹配项和行不是最后一行,则将以下行添加到该行,然后\n用空格替换

参考:我如何使用 sed 来替换多行字符串

于 2016-04-22T11:45:50.830 回答
2

我知道这很难接受,但老实说 - sed 用于单个行的简单替换以及您应该使用 awk 的任何其他内容。我发现 sed 非常有用,并且几乎每天都在使用它 30 多年,但是在 1970 年代中期,当 awk 被发明时,除了对单个行进行简单替换之外,所有 sed 构造都变得过时了。

$ seq 4 | awk '{printf "%s%s", s, $0; s=ORS} /2/{s=OFS} END{print ""}'
1
2 3
4

2s加入线路怎么样:

$ seq 10 | awk '{printf "%s%s", $0, (NR%2?OFS:ORS)}'
1 2
3 4
5 6
7 8
9 10

尝试修改连接 2 行的 sed 脚本以改为连接 5 行。2与将number更改为 number 的简单、明显的 awk 调整相比5

$ seq 10 | awk '{printf "%s%s", $0, (NR%5?OFS:ORS)}'
1 2 3 4 5
6 7 8 9 10

以上将适用于所有操作系统上的所有 awk,并且如果/当您的需求发生变化时,只需进行最小的更改即可轻松增强 - 这是您应该学习使用 awk 而不是 sed 的两个非常重要的原因。

于 2016-04-23T02:15:50.070 回答