如何在搜索中使用awk变量?

4
如何在搜索中使用awk变量?
Name="jony"
awk -v name="$Name" '/name/ {print $0}' file

这将搜索字符串name,而不是实际上为jony$Name

3个回答

6

正确的做法是,awk不会识别/ /中的变量。你可以这样做:

Name="jony"
awk -v name="$Name" '$0 ~ name' file

由于printawk的默认行为,因此我们可以避免在此处使用它。


1
你能解释一下这里的 ~ 是做什么用的吗?我尝试了一下,但它没有起作用。
`echo "Hi this is jony" | awk '$0 ~ jony'
输出: Hi this is jony`
echo "Hi this is jony" | awk '$0 ~ holmes' 输出: Hi this is jony
我不明白为什么它会打印出这行,即使它里面没有“holmes”。
- Jagan
4
来自指南:~(波浪号)~运算符正则表达式也可以用于匹配表达式。这些表达式允许您指定要匹配的字符串;它不需要是整个当前输入记录。两个运算符~!~执行正则表达式比较。使用这些运算符的表达式可以用作模式,或在if、while、for和do语句中使用。 - jaypal singh
1
@Jagan 当你执行 echo "Hi this is jony" | awk '$0 ~ holmes' 时,awkhomes 视为未定义的变量,因此打印该行。如果你想让 awk 将其视为字面字符串,你需要将其加上引号。 - jaypal singh

1
希望我理解问题的正确:为什么不尝试以下方法:
awk '/'"$Name"'/ { print } ' testfile 

1
不,绝对不能这样做。这种方法非常容易出错和产生漏洞。使用“-v”来设置变量,或者查看comp.unix.shell FAQ http://cfajohnson.com/shell/cus-faq-2.html#Q24以获取更好的替代方案。 - Ed Morton

1

当编写AWK单行脚本时,您可以使用单引号或双引号引用脚本。在后一种情况下,Shell直接进行所有替换,因此您不需要通过-v选项将变量传递到脚本中:

Name="jony"
awk "/$Name/" file
# this works. after shell has performed substitutions, the line looks like
awk "/jony/" file

[不好!]或者如果名称中不包含空格,甚至可以不用引号:

awk /$Name/ file

所有的简单性都会在你想要在脚本中使用$时消失,包括使用$0、$1等awk特殊变量,因为你必须转义美元符号以防止shell变量扩展。
awk "/$Name/ {print \$0}"

此外,您还需要转义双引号以将字面文本添加到脚本中。看起来有些笨拙:
awk "/$Name/ {print \"Found in: \" \$0}"

总之,使用双引号否定正则表达式会导致shell错误:
awk "!/$Name/"
#error> ... event not found ...

如果$Name本身包含!标记,就会发生错误。这使得使用双引号不可靠。
因此,为了安全起见,请优先使用单引号 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接