【问题标题】:Extract lines between two patterns with awk and a variable regex使用 awk 和变量正则表达式提取两个模式之间的行
【发布时间】:2014-07-17 15:22:49
【问题描述】:

我正在寻找一种使用 awk 提取两个模式之间的线条的方法 的变量。每个部分在下一个部分开始的地方结束。

示例文件:

[ SECTION_1 ]
info 1
info 2
info 3
[ SECTION_2 ]
info 4
info 5
info 6
[ SOMETHING_SOMETHING_DARK_SIDE ]
...
[ WE_have_COokIES ]

awk '/^\[ SECTION_1 \]/{p=1;next} /^\[ [!-~]+ \]/{p=0} p' "${MY_FILE_PATH}"

我得到了我想要的:

info 1
info 2
info 3

但我想要这样的东西:

function get { 
  awk '/^\[ "$1" \]/{p=1;next} /^\[ [!-~]+ \]/{p=0} p' "${MY_FILE_PATH}"
}

似乎没有任何效果:(有什么想法或提示吗?

【问题讨论】:

  • 你如何得到你想要的,那个 awk 不会打印任何东西?
  • 哦,谢谢,里面有错字。应该是.../{p=0} p。我在我的问题中更正了它!

标签: regex awk multiline


【解决方案1】:

你用双引号引用它是错误的。位置参数$1 没有展开,因为它仍然用单引号括起来。应该是:

function get { 
    awk '/^\[ '"$1"' \]/{p=1;next} /^\[ [!-~]+ \]/{p=0} f' "${MY_FILE_PATH}"
}

也许另一个好方法是使用-v。至少可以避免严重的语法错误:

function get { 
    awk -v s="$1" '$0 ~ "^\\[ " s " \\]"{p=1;next} /^\[ [!-~]+ \]/{p=0} f' "${MY_FILE_PATH}"
}

【讨论】:

  • 永远不要使用第一种方法,因为它充满了警告和潜在的错误。第二个很接近,但您需要使用字符串文字对 RE 元字符进行双重转义 - 如写的 \[[ 相同,您需要 \\[
  • @EdMorton 是的,你是对的。我错过了引用。
【解决方案2】:

它可能更简单/更清晰:

awk -v sect="$1" '/^\[ [!-~]+ \]/{ f = ($0 ~ "^\\[ " sect " \\]") } f' file

【讨论】:

    【解决方案3】:

    这里你有一个完全不同的使用 sed 的方法; 它首先使用正则表达式去掉以 [
    开头的行 然后它会删除空行。

    $ sed 's/^\[.*//g' sections.txt | sed '/^$/d'
    info 1
    info 2
    info 3
    info 4
    info 5
    info 6
    

    【讨论】:

    • ...,但是不满足获取指定section本身内容的要求。
    猜你喜欢
    • 1970-01-01
    • 2021-12-02
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    • 2014-07-18
    • 1970-01-01
    相关资源
    最近更新 更多