【问题标题】:Change lines that match a pattern in between delimiters using awk使用 awk 更改与分隔符之间的模式匹配的行
【发布时间】:2011-08-29 06:37:30
【问题描述】:

我有一个类似这样的输入文件:

some line
some other line
another line
start_delimiter
  interesting stuff
  more interesting stuff
  even more interesting stuff
end_delimiter
possibly more stuff

我想操作 start_delimiter 和 end_delimiter 之间匹配正则表达式模式的行并将结果写入输入文件。例如,将 '//' 添加到包含单词 'more' 的行的开头(只要这些行位于分隔符之间):

some line
some other line
another line
start_delimiter
  interesting stuff
  //more interesting stuff
  //even more interesting stuff
end_delimiter
possibly more stuff

我可以通过这种方式获取分隔符之间的文本部分:

awk '/start_delimiter/,/end_delimiter/' inputfile

如果我将它通过管道传输到另一个 awk,我可以更改我感兴趣的行:

awk '/more/ {sub(/^/,"//")}1'

我不确定如何返回并用新内容替换分隔部分。有任何想法吗?单线加分。

【问题讨论】:

    标签: awk delimiter substitution


    【解决方案1】:

    你需要类似的东西

    awk '/start_delimiter/,/end_delimiter/{
      if ($0 ~ /^more/ ) { print "//" $0 } 
      else print $0
    }
    !/start_delimiter/,/end_delimiter/ print $0' inputfile
    

    第二个范围模式是打印范围之外的其他行(由前导“!”指定)(我现在没有办法测试,所以尝试移动“!”如果它不能像这样工作)

    我希望这会有所帮助。

    【讨论】:

    • 或更短的版本:awk '/^start_delim/,/^end_delim/ { if ($0 ~ /more/){$0="//" $0} } {print}' file
    • 是的,好多了,就像@Andrew 的解决方案一样。为你们俩喝彩,感谢分享!
    【解决方案2】:
    /start_delimiter/ {inblock=1}
    /end_delimiter/ {inblock=0;}
    { if (inblock==1 && (/more/)) { print "//" $0 } else print $0}
    

    【讨论】:

    • 我只是有同样的想法。如果我有机会回答,我会写同样的东西 +1 来自我
    • 也谢谢你 - 这是我第一次用 awk 做的不仅仅是“打印 $5” :)
    【解决方案3】:

    对于一个班轮狂热分子:

    awk '/^(start_delim|end_delim)/{f=f?0:1}f&&/more/{$0="//" $0}1' file
    

    添加了行首^ 锚点以避免块分隔符嵌入行中间时造成混淆。

    【讨论】:

    • 多一点解释会很好,不过 +1 单线。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 2018-02-19
    • 1970-01-01
    相关资源
    最近更新 更多