我正在尝试找到一个字符串模式,该字符串模式由结论一词组成,后跟字段$ 2的值,字段$ 3来自字段$ 5中的相同记录.
例如,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...|
Run Code Online (Sandbox Code Playgroud)
所以在这个例子中我只想要打印第一条记录,因为它有"结论"字样,后面substance1跟着substance2.
这是我正在尝试但它不起作用:
awk 'BEGIN{FS="|";IGNORECASE=1}{if ($5 ~ /CONCLUSIONS.*$2.*$3/) {print $0}}' my_file.txt
Run Code Online (Sandbox Code Playgroud)
任何帮助深表感谢
$ awk 'BEGIN{FS="|";IGNORECASE=1} $5 ~ "conclusions.*" $2 ".*" $3' my_file.txt
1|substance1|substance2|red|CONCLUSIONS: the effect of SUBSTANCE1 and SUBSTANCE2 in humans...|
Run Code Online (Sandbox Code Playgroud)
BEGIN{FS="|";IGNORECASE=1}
这部分与问题中的代码没有变化.
$5 ~ "conclusions.*" $2 ".*" $3
这是一个条件:如果$5匹配由连接在一起的四个字符串组成的正则表达式,则为真: "conclusions.*"和$2,和".*",和$3.
我们没有为此条件指定任何操作.因此,如果条件为true,则awk执行默认操作以打印该行.
考虑:
$ echo "aa aa" | awk '$2 ~ /$1/'
Run Code Online (Sandbox Code Playgroud)
此行不打印任何内容,因为awk不会替换正则表达式中的变量.
请注意,此处未找到匹配项:
$ echo '$1' | awk '$0 ~ /$1/'
Run Code Online (Sandbox Code Playgroud)
这里没有匹配,因为在正则表达式中,$只匹配一行的末尾.所以,/$1/只会匹配一行后跟一个1.如果我们想在这里得到一个匹配,我们需要逃避美元符号:
$ echo '$1' | awk '$0 ~ /\$1/'
$1
Run Code Online (Sandbox Code Playgroud)
要获得使用awk变量的正则表达式,我们可以作为此答案的基础,执行以下操作:
$ echo "aa aa" | awk '$2 ~ $1'
aa aa
Run Code Online (Sandbox Code Playgroud)
这确实成功地产生了匹配.
正如Ed Morton在评论中所建议的那样,坚持认为这些物质只与整个单词相匹配可能很重要.在这种情况下,我们可以使用\\<...\\>限制物质匹配到整个单词.从而:
awk 'BEGIN{FS="|";IGNORECASE=1} $5 ~ "conclusions.*\\<" $2 "\\>.*\\<" $3 "\\>"' my_file.txt
Run Code Online (Sandbox Code Playgroud)
这样,substance1就不会匹配了substance10.