AWK 在正则表达式中使用字段值

AWK use value of field in regex

我正在尝试从字段 $5 中的同一记录中查找由单词 CONCLUSION 后跟字段 $2 和字段 $3 的值组成的字符串模式。

例如my_file.txt用“|”隔开:

1|substance1|substance2|red|CONCLUSIONS: the effect of SUBSTANCE1 and SUBSTANCE2 in humans...|
2|substance3|substance4|red|Conclusions: Substance4 is not harmful...|
3|substance5|substance6|red|Substance5 interacts with substance6...|

所以在这个例子中,我只想打印第一条记录,因为它有单词 "CONCLUSIONS",然后是 substance1,然后是 substance2

这是我正在尝试的方法,但它不起作用:

awk 'BEGIN{FS="|";IGNORECASE=1}{if ( ~ /CONCLUSIONS.*.*/) {print [=11=]}}' my_file.txt

非常感谢任何帮助

$ awk 'BEGIN{FS="|";IGNORECASE=1}  ~ "conclusions.*"  ".*" ' my_file.txt
1|substance1|substance2|red|CONCLUSIONS: the effect of SUBSTANCE1 and SUBSTANCE2 in humans...|

工作原理

  • BEGIN{FS="|";IGNORECASE=1}

    这部分与问题中的代码没有变化。

  • ~ "conclusions.*" ".*"

    这是一个条件:如果 </code> 匹配由四个字符串连接在一起组成的正则表达式:<code>"conclusions.*"</code>、<code>".*"</code>.</p> <p>我们没有为此条件指定任何操作。因此,如果条件为真,<code>awk 将执行打印该行的默认操作。

更简单的例子

考虑:

$ echo "aa aa" | awk ' ~ //'

此行不打印任何内容,因为 awk 不会替换正则表达式中的变量。

观察这里也没有找到匹配项:

$ echo '' | awk '[=12=] ~ //'

这里没有匹配项,因为在正则表达式中,$ 只匹配行尾。因此,// 只会匹配行尾后跟 1。如果我们想在这里匹配,我们需要转义美元符号:

$ echo '' | awk '[=13=] ~ /$1/'

要获得使用 awk 变量的正则表达式,我们可以按照此答案的基础执行以下操作:

$ echo "aa aa" | awk ' ~ '
aa aa

这确实成功地产生了匹配。

进一步改进

正如 Ed Morton 在评论中建议的那样,坚持物质仅在整个单词上匹配可能很重要。在这种情况下,我们可以使用 \<...\> 将实质匹配限制为整个单词。因此:

awk 'BEGIN{FS="|";IGNORECASE=1}  ~ "conclusions.*\<"  "\>.*\<"  "\>"' my_file.txt

这样,substance1就不会匹配到substance10