我想将几个shell变量传递给awk命令,然后使用regex在字段中匹配它们。但是,我希望变量的内容在正则表达式中被视为文字。所有这些都是针对输入文件的每一行完成的。
所以这个
123^A
会出现在这些东西里
123^A|field2|field3
123^A~000^A|field2|field3
000^A~123^A|field2|field3
000^A~123^A~999^A|field2|field3
但这些都不是
123^B|field2|field3
1234^A|field2|field3
123|field2|field3
123~000|field2|field3
不起作用的例子:
read inputfile?'Enter the input file: '
read tackedonvalue?'Enter the value to tack onto each input value: '
read searchfile?'Enter the search file: '
read fieldnum?'Enter the field number to search: '
read delim?'Enter the field delimiter: '
while read -r SEARCHTERM
do awk -F"${delim}" -v a="(^|~)${SEARCHTERM}${tackedonvalue}(~|$)" -v COL="${fieldnum}" '$COL ~ /a/' ${searchfile} >> output_file.txt
done < ${inputfile}
- “123”是来自输入的
$inputfile
变量的一行 - “^A”是输入中的
$tackedonvalue
变量
这个例子不起作用的原因是,$tackedonvalue
变量中通常会有^
字符,然后需要对正则表达式进行转义。(在输入中手动转义它们不是一个选项。)在该变量中输入的其他特殊字符也可能需要转义,因此我不希望在每种情况下都必须查找/替换每个特殊字符。
另一个我第一次尝试但无法正常工作的例子(与之前相同的输入提示和while read
):
awk -F"${delim}" -v a="${SEARCHTERM}" -v b="${tackedonvalue}" -v COL="$fieldnum" '$COL ~ ("(^|~)" a b "(~|$)")' ${searchfile} >> output_file.txt
我认为这并不起作用,因为开始和结束锚,但我不知道如何修复这些,所以不得不使用正则表达式常量(/pattern/带正斜杠)。
如果第二个例子的锚点是固定的,并且变量内容被视为文字,那么这将是另一种途径。
P.S. -第一篇文章,所以让我知道需要改变/改进/提供什么。
2条答案
按热度按时间qfe3c7zg1#
您需要对搜索词中的
^
进行转义,因为它在正则表达式中具有特殊含义。如果您的搜索词可能包含在正则表达式中具有特殊含义的其他字符,则需要将它们全部替换。这在awk中更容易做到:
顺便说一句,你不应该使用全大写的shell变量。约定是这些名称保留给环境变量。
但也许你根本不应该使用模式匹配。我认为您可以在
~
字符上拆分字段,然后在该数组上循环测试是否有任何元素与搜索字符串匹配。vsmadaxz2#
我不了解awk,但用perl很容易做到:
正则表达式中
\Q
和\E
之间的任何内容都会自动转义/忽略任何元字符。