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
。
我正在尝试从字段 $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
。