代码之家  ›  专栏  ›  技术社区  ›  Matias Barrios

用sed连接某些行

sed
  •  2
  • Matias Barrios  · 技术社区  · 6 年前

    我有一个输入,如下所示:

    1
    2
    
    3
    4
    5
    
    6
    

    我想用sed将其转换为:

    12
    345
    6
    

    我知道使用其他工具可以很容易地完成它,但我想将SED作为一种学习练习来专门完成它。 我尝试过:

    sed ':x ; /^ *$/{ N; s/\n// ; bx; }'
    

    但它打印:

    123456
    

    有人能帮我修一下吗?

    3 回复  |  直到 6 年前
        1
  •  4
  •   melpomene    6 年前

    引用 GNU sed manual :

    处理文本块(如段落(而不是逐行)的常用技术是使用以下结构:

    sed '/./{H;$!d} ; x ; s/REGEXP/REPLACEMENT/'
    
    1. 第一个表达式, /./{H;$!d} 对所有非空行进行操作,并将当前行(在模式空间中)添加到保留空间。在除最后一行以外的所有行上,将删除模式空间并重新启动循环。

    2. 其他表达式 x s 仅在空行(即段落分隔符)上执行。这个 X 命令将保留空间中的累积行提取回模式空间。这个 s/// 然后,命令对段落中的所有文本(包括嵌入的换行符)进行操作。

    事实上,

    sed '/./{H;$!d} ; x ; s/\n//g'
    

    做你想做的。

        2
  •  2
  •   Ed Morton    6 年前

    fwiw下面介绍如何在Unix中真正执行该任务:

    $ awk -v RS= -v OFS= '{$1=$1}1' file
    12
    345
    6
    

    以上内容适用于任何UNIX设备。

        3
  •  1
  •   Tyl    6 年前

    GNU awk 途径:

    $ awk -F"\n" '{gsub("\n","");}1' RS='\n{2,}' file
    12
    345
    6
    

    注意,它将添加一个尾随新行 \n 在最后一行之后。