【问题标题】:Substitution between two patterns with line offset via sed or awk通过 sed 或 awk 在具有行偏移的两个模式之间进行替换
【发布时间】:2017-09-27 18:07:15
【问题描述】:

我有一个大文件,内容由标题分隔。

如何通过 sed 或 awk 替换文件中特定标题之后的行和特定字符串(不包括在内)之前的行之间的文本?

示例:我想在下面的文件中将header1 之后的行和string_near_end_of_file 之前的行(不包括)之间的文本替换为EXAMPLE...

...

header1
#######
content1

header2
#######
content2

...

string_near_end_of_file

...

预期结果:

...

header1
#######
EXAMPLE

string_near_end_of_file

...

我知道 sed '/pattern1/,/.. pattern2/c\substition_string' 文件替换 pattern1pattern2 之间的 substition_string 并且 sed -n '/pattern/{n;p}' filepattern 匹配之后打印该行,但我现在不确定是否将其放在一起以实现我的规定的目标。

任何帮助将不胜感激!

【问题讨论】:

    标签: bash awk sed


    【解决方案1】:

    你可以使用这个awk 命令:

    awk '/string_near_end_of_file/{p=0} !p; $1=="header1"{p=1; print "######\nEXAMPLE\n"}' file
    

    输出:

    ...
    
    header1
    ######
    EXAMPLE
    
    string_near_end_of_file
    
    ...
    

    【讨论】:

    • 刚刚更新了我的问题,使其更加清晰。
    • 根据您编辑的问题检查我的更新答案。
    • 谢谢!在我接受你的回答之前,我只是想知道如果header1 包含一个空格(如:header 1)你会怎么做?我刚刚意识到我在我的问题中犯了一个错误,我应该提到标题包含空格 - 对此表示歉意!
    • 如果header值中有空格,那么可以这样使用:awk '/string_near_end_of_file/{p=0} !p; /header 1/{p=1; print "######\nEXAMPLE\n"}' file
    • 是的。谢谢老兄!
    【解决方案2】:

    GNU sed:

    sed -e '/header1/,/string_near/{/header1/{n;s/$/\nEXAMPLE\n/;n};/string_near/!d}' file

    范围内:

    • /header1/{n; - 跳过 header1 行
      • s/$/\nEXAMPLE\n/; - 将 ### 行尾替换为 \nEXAMPLE\n
      • n} 保留### 和EXAMPLE 行
    • /string_near/!d; - 删除除 string_near 之外的其他行

    sed 很讨厌在块中重复 /START/,/END/ 模式的要求。您有时可以使用// 来表示最后一个正则表达式,但任何嵌套的正则表达式都会限制它在 /START/,/END/ 范围内的使用。

    请注意,一些 sed 实现需要在大括号前使用分号。

    还要注意,我使用替换行结束 s/$/\nEXAMPLE\n/ 因为在命令行中内联比使用 sed 的 c ai 命令更容易,这需要一个换行符命令字符串。

    【讨论】:

      【解决方案3】:

      Awk 解决方案(假设 header 行后面总是跟####### 行):

      awk -v repl="EXAMPLE" '!f && /header/{ f=1; n=NR; getline nl; r=$0 ORS nl }
             /string_near_end_of_file/{ f=0; print r ORS repl ORS ORS $0; next }
             f && NR>n{ next }1' file
      

      输出:

      ...
      
      header1
      #######
      EXAMPLE
      
      string_near_end_of_file
      
      ...
      

      【讨论】:

        猜你喜欢
        • 2014-09-07
        • 1970-01-01
        • 2022-06-10
        • 1970-01-01
        • 2012-02-10
        • 2013-03-12
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        相关资源
        最近更新 更多