【问题标题】:How to use sed to replace only on lines matching a regular expression?如何使用 sed 仅替换匹配正则表达式的行?
【发布时间】:2013-12-25 16:28:13
【问题描述】:

我有一个由以下形式的字符串组成的文件:

21-11-2000
1
2
3
4
5
22-11-2000
1
2
3
4
5

我想将其转换为:

21-11-2000,1,2,3,4,5
22-11-2000,1,2,3,4,5

因此我会使用 sed 两次。首先用逗号替换与[0-9][0-9]\-[0-9][0-9]\-[0-9][0-9] 匹配的每一行的行尾,然后再进行一次 sed 扫描以替换从行首到逗号不匹配相同模式的每一行。

会有更简单的方法吗?

【问题讨论】:

    标签: unix sed


    【解决方案1】:

    awk '{
        if ($1 ~ "^[0-9]+-[0-9]+-[0-9]+") {
            k=$1
            next
        }
        arr[k]=arr[k]","$1
    }
    END{for (a in arr) print a arr[a]}
    ' file
    

    【讨论】:

      【解决方案2】:

      这里有一些awk 的变体:

      awk -F- '{printf (NF>2?RS:",")"%s",$0}' t
      
      21-11-2000,1,2,3,4,5
      22-11-2000,1,2,3,4,5
      

      如果每条记录总是6行,这是最好的:

      awk 'NR%6{printf "%s,",$0;next}1' t
      21-11-2000,1,2,3,4,5
      22-11-2000,1,2,3,4,5
      

      【讨论】:

        【解决方案3】:

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

        sed '/-/{:a;$!N;/\n[0-9]$/s/\n/,/;ta};P;D' file
        

        【讨论】:

          【解决方案4】:

          您可以使用哪些工具?如果您的输入文件与您描述的完全一样,则以下单行将起作用。

          cat input | awk 1 ORS=',' | perl -pi -e 's/(\d),(\d+-|$)/$1\n$2/g'
          

          【讨论】:

          • 对 perl 无用 cat 和 -i 无用
          • @sputnick 你也可以声称xargs 是无用的,因为它为了提供方便或清晰而浪费了一个过程。在此处使用cat 通过清晰的管道序列给出了更好的说明,而不是在第一和第二处理步骤之间放置输入,即。一个-i 标志确实“无用”here,但为 OP 提供了一个真正有用的起点,让他们自己进行一些研究并了解如何使用 Perl 自动操作文件(如果他们愿意,甚至可以制作备份副本)。我希望 OP 能够查找答案的每个部分并从中受益。
          【解决方案5】:

          使用 sed(不仅是数字行)

          sed '/-/{:a;N;/\n[^-]*$/s/\n/,/;ta};P;D' file
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-06-17
            • 1970-01-01
            • 1970-01-01
            • 2019-04-14
            • 2021-11-14
            • 2012-05-16
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多