【问题标题】:Replace several lines by one using sed使用 sed 替换几行
【发布时间】:2021-03-11 05:08:52
【问题描述】:

我有这样的输入:

This_is(A)
    Goto(B,condition_1)
    Goto(C,condition_2)

This_is(B)
    Goto(A,condition_3)

This_is(C)
    Goto(B,condition_1)

我希望它变成这样

    (A,B,condition_1)
    (A,C,condition_2)

    (B,A,condition_3)

    (C,B,condition_1)

有人知道如何用 sed 做到这一点吗?

【问题讨论】:

    标签: regex sed


    【解决方案1】:

    假设您真的不需要使用 sed 执行此操作,这将在每个 UNIX 机器上的任何 shell 中使用任何 awk 来工作:

    $ awk -F'[()]' '/^[^[:space:]]/{s=$2; next} {sub(/[^[:space:]]*\(/,"("s",")} 1' file
        (A,B,condition_1)
        (A,C,condition_2)
    
        (B,A,condition_3)
    
        (C,B,condition_1)
    

    【讨论】:

    • 我想要一些基本 unix 的东西。我认为 sed 是工具,但这绝对是要走的路。谢谢
    【解决方案2】:

    这是一个可能的sed 解决方案,我在其中硬编码了一些位,例如This_isGoto,因为OP 没有说明这些字符串是否在实际文件中沿文件更改:

    sed '/^This_is/{:a;N;s/\(^This_is(\(.\)).*\)\(\n *\)Goto(\([^)]*)\)$/\1\3(\2,\4/;$!ta;s/[^\n]*\n//}' input_file
    

    (不幸的是,使用所有这些括号,使用-E 并不会大大缩短命令。)

    如果分成多行,代码的可读性会稍微好一些:

    sed '/^This_is/{
                     :a
                     N
                     s/\(^This_is(\(.\)).*\)\(\n *\)Goto(\([^)]*)\)$/\1\3(\2,\4/
                     $!ta
                     s/[^\n]*\n//
                   }' os
    

    在这里您可以看到代码仅对以This_is 开头的行执行操作;当程序遇到这些行时,它会执行以下操作。

    • 它使用N 命令将下一行附加到模式空间(穿插\ns),
    • 它尝试用s/…/…/ 进行替换,这实际上是尝试在This_is(x) 中选择x,并将其放在多行上最后一个Goto( 之后,
    • 只要后一个动作成功,它就会一直这样做(ta 分支到 :a,如果 s 成功)并且最后一行没有被读取(@987654337 @ 匹配除最后一行之外的所有行);
      • 确实,这是一个 do-while 循环,其中:a 标记入口点,如果 while 条件为真,控件将在此处跳转,ta 是评估逻辑条件的命令。李>
    • 当上述 while 循环终止时,较短的 s/…/…/ 命令会从多行模式空间中删除前导行,即 This_is 行。

    【讨论】:

      【解决方案3】:

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

      sed -E '/^\S.*\(.*\)/{h;d};G;s/\S+\((.*\))\n.*(\(.*)\).*/\2,\1/;P;d' file
      

      如果一行以非空白字符开头并包含括号,请将其复制到保留空间 (HS),然后将其删除。

      否则,追加 HS,删除开头括号之前的非白色字符,从存储的值中插入括号之间的值,添加逗号并打印第一行,然后删除整个模式空间。

      注意不满足替换条件的行将保持不变。

      使用 GNU 并行和 sed 的替代解决方案:

      parallel --pipe --recstart T -kqN1 sed -E '1{h;d};G;s/\S+\((.*)\n.*(\(.*)\).*/\2,\1/;P;d' <file
      

      【讨论】:

        猜你喜欢
        • 2022-01-19
        • 2020-02-02
        • 1970-01-01
        • 2011-03-22
        • 2021-09-25
        • 2013-10-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多