【问题标题】:using sed to replace a newline that starts with any digit使用 sed 替换以任何数字开头的换行符
【发布时间】:2019-08-13 14:42:25
【问题描述】:

我一直在谷歌上搜索,但找不到有效的答案。我有一个文件,其中大多数行都以字符串开头。但是,有几行以数字开头(长度不同)。我想使用 sed 从这些行中删除换行符,以便后面的数字和内容出现在前面的行中。

我正在使用 mac,所以我正在使用 bash shell。

例子:

Test 1,2,3,
41
Test 5,6,7,
8800
Test 9, 10
Test 11, 12

应该结束:

Test 1,2,3,41
Test 5,6,7,8800
Test 9, 10
Test 11, 12

【问题讨论】:

    标签: sed


    【解决方案1】:

    一个简短的sed 就可以了:

    sed -zE 's/(,)[[:space:]]*[\n\r]+/\1/g'
    

    sed参数分解:

    • -z:使用以空结尾的行来允许 sed 搜索替换换行符。
    • -E:使用扩展的正则表达式语法
    • 's/(,)[[:space:]]*[\n\r]+/\1/g':搜索,,后跟一些空格和任意数量的换行符或换行符,并替换为捕获的,。结果是当最后一个, 之后没有任何内容时,它将删除换行符和尾随空格

    产生的输出:

    Test 1,2,3,41
    Test 5,6,7,8800
    Test 9, 10
    Test 11, 12
    

    【讨论】:

    • 不错的 sed 支持 zE 选项。我不确定 Mac sed 是否,因为我希望它遵循 BSD,其 sed 知道 -E 但不知道 -z。但是,如果 OP 已经或可以安装 GNU sed,那么这很简短。
    【解决方案2】:

    sed 一次处理一行。可以使用它来连接行,但是一旦输出一行而不将下一行连接到它,就为时已晚。

    您可能会得到一个答案,建议您使用 awk 执行此操作,这确实可能会更好,但由于您专门询问了 sed,因此 可以使用它为目的。有几种方法可以做到这一点。这个应该适用于任何符合 POSIX 的sed

     sed ':1; $ { s/\n\([0-9]\)/\1/g; n }; N; b1'
    

    说明:sed 表达式是一系列以分号分隔的命令,可以更详细(并带有解释性 cmets)表示为

    # Label for looping back to the start of this script
      :1
    
    # If we're on the last line
    $ {
        # Remove all newlines that are immediately followed by a digit
        s/\n\([0-9]\)/\1/g
    
        # Finish this sed cycle, printing the result (will terminate because no more lines)
        n
      }
    
    # Append a newline to the pattern space, followed by the next line of input
      N
    
    # jump to label 1
      b1
    

    换句话说,它将吞下所有输入,然后一次性执行所有替换。虽然与他们的完全不同,但这是受到@LéaGris 版本的启发。

    【讨论】:

      【解决方案3】:

      这可能对你有用(GNU sed):

      sed 'N;/\n[0-9]/s/\n//;P;D' file
      

      添加下一行,如果该行以数字开头,则删除换行符。打印然后删除模式空间中的第一行并重复。

      注意这不会将整个文件拖入内存,而是在模式空间中最多保留两行。

      【讨论】:

      • 不错。我一直在寻找类似的东西,但不知道D 命令将如何促进它。
      【解决方案4】:

      如果缺少数字的行以逗号 , 结尾,您可以这样做:

      awk '{printf /,$/?"%s":"%s\n",$0}' file
      Test 1,2,3,41
      Test 5,6,7,8800
      Test 9, 10
      Test 11, 12
      

      它打印换行符取决于逗号或不是在行尾的逗号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-07
        • 1970-01-01
        • 2018-05-13
        • 1970-01-01
        • 2014-04-11
        相关资源
        最近更新 更多