【问题标题】:Unix: Modify a line in a file only if it is preceded by a particular lineUnix:仅当文件中的一行前面有特定行时才修改它
【发布时间】:2020-03-29 04:00:09
【问题描述】:

我有一个像这样的文本文件 -

Random text
Some more random text ...

TEXT_CATEGORY_A(
    SOME_INFO, A,
    "Some random text.",
    "Other info.",
    )
TEXT_CATEGORY_B(
    SOME_INFO, B,
    "Some random text.",
    "Other info.",
    )
TEXT_CATEGORY_C(
    SOME_INFO, C,
    "Some random text.",
    "Other info.",
    )

等等... 我想从每个 TEXT_CATEGORY 容器的最后一句中删除逗号,即从 -

"Other info.",

所以文件的最终形式应该是这样的 -

Random text
Some more random text ...

TEXT_CATEGORY_A(
    SOME_INFO, A,
    "Some random text.",
    "Other info."
    )
TEXT_CATEGORY_B(
    SOME_INFO, B,
    "Some random text.",
    "Other info."
    )
TEXT_CATEGORY_C(
    SOME_INFO, C,
    "Some random text.",
    "Other info."
    )

如果我能以某种方式发现下一行只包含) 字符,那么我可以解决这个问题。 我无法使用 sed 解决此问题,因为它逐行读取文件。有什么方法可以让我了解下一行的内容还是有其他方法可以解决这个问题?

【问题讨论】:

    标签: shell awk sed scripting


    【解决方案1】:

    灵活搭配sed 命令:

    sed -E '/,$/N; s/([^,]+),\s+\)$/\1\n)/' file
    
    • /,$/ - 匹配以 , 结尾的行
    • N - 将下一行捕获到缓冲区空间中
    • \1 - 第一个捕获的组(指向([^,]+)

    输出:

    Random text
    Some more random text ...
    
    TEXT_CATEGORY_A(
        SOME_INFO, A,
        "Some random text.",
        "Other info."
    )
    TEXT_CATEGORY_B(
        SOME_INFO, B,
        "Some random text.",
        "Other info."
    )
    TEXT_CATEGORY_C(
        SOME_INFO, C,
        "Some random text.",
        "Other info."
    )
    

    【讨论】:

    • 嗨@RomanPerekhrest,我尝试了你的解决方案,但不知何故它没有修改任何东西。我稍微修改了脚本 - ` sed -E '/,$/N; s/",$/"/' file ` 然后就可以正常工作了。
    【解决方案2】:

    第一个解决方案:您能否尝试以下操作。在这里使用tac + awk。这应该更快。

    tac Input_file | awk '{sub(/,/,"")} 1' | tac
    

    说明:为上述代码添加说明。

    tac Input_file    ##Using tac to print Input_file inn reverse order.
    awk '{            ##Using tac command output to awk program from here.
      sub(/,/,"")     ##Using sub to substitute very first occurrence of comma with NULL here.
    }                 ##Closing BLOCK here.
    1                 ##Mentioning 1 will print edited/non-edited line here.
    ' | tac           ##Passing previous awk command output to tac command now and making it in its normal form.
    


    第二个解决方案: 使用 GNU awk

    awk -v RS="" '
    match($0,/.*,/){
      print substr($0,RSTART,RLENGTH-1) substr($0,RSTART+RLENGTH)
    }
    ' Input_file
    

    说明:为上述代码添加说明。

    awk -v RS="" '                                                    ##Starting awk program from here and setting RS(record separator) as NULL here.
    match($0,/.*,/){                                                  ##Using match function of awk to match a regex till last occurrence of comma.
      print substr($0,RSTART,RLENGTH-1) substr($0,RSTART+RLENGTH)     ##Printing substring from RSTART to till value of RLENGTH-1 then again mentioning substrnig from RSTART+RLENGTH to till end of Input_file.
    }                                                                 ##Closing BLOCK for match condition here.
    '  Input_file                                                       ##Mentioning Input_file name here.
    

    【讨论】:

    • @anubhava,谢谢先生。由于我没有非 GNU awk 不能说,干杯。
    • @RavinderSingh13 第一个解决方案是从每行中删除逗号。第二种解决方案是仅从最后一个“其他信息”中删除逗号。即来自属于 TEXT_CATEGORY_C 的那个
    • @Harshu,对我来说都很好,你能通过一次cat -v Input_file 来检查一下你的 Input_file 中是否有控制 M 个字符吗?
    【解决方案3】:

    使用 sed 解决如下 -

    sed -E '/,$/N; s/",$/"/' file
    

    这是对@RomanPerekhrest 提供的解决方案的轻微修改。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多