我想从管道分离文件中提取一个特定模式存在的子串,因此我使用了下面的命令,
awk -F ":" '/REWARD REQ. SERVER HEADERS/{print $1, $2, $3, $4}' sample_profile.txt
给你,“奖励”。SERVER HEADERS'是一个模式,将在文件中搜索,并在冒号分隔的行上打印其前4个部分。
现在,我想发送bash变量作为模式。所以我使用了命令下的方式,但它不起作用。
awk -v pat="$pattern" -F ":" '/pat/{print $1, $2 , $3, $4 } sample_profile.txt
如何在一个awk
命令中使用-v
和-F
?
4条答案
按热度按时间vc9ivgsu1#
如果你想通过变量提供模式,你需要使用
~
来匹配它:在您的情况下,问题与
-F
无关。问题是当你想让
pat
成为一个变量时,/pat/
的用法。如果输入/pat/
,awk
会将其理解为文字“pat”,因此它会尝试匹配包含字符串“pat”的那些行。总的来说,你的代码应该是:
请参阅范例:
给定此文件:
让我们寻找包含“hello”的行:
现在让我们试着寻找“pat”,包含在一个变量中,就像你做的那样:
现在让我们使用
$0 ~ pat
表达式:当然,您可以使用这样的表达式只匹配一个字段,比如
awk -v pat="$pattern" '$2 ~ pat' file
等等。从GNU Awk用户指南→ 3.1如何使用正则表达式:
当一个正则表达式用斜杠括起来时,比如/foo/,我们称它为正则表达式常量,就像5.27是一个数值常量,而“foo”是一个字符串常量。
GNU Awk用户指南→ 3.6使用动态正则表达式:
"~“或”的右边!“~”运算符不需要是正则表达式常量(即,斜杠之间的字符串)。它可以是任何表达。如果需要,将计算表达式并将其转换为字符串;然后将字符串的内容用作regexp。以这种方式计算的正则表达式称为动态正则表达式或计算正则表达式:
这将digits_regexp设置为描述一个或多个数字的regexp,并测试输入记录是否与此regexp匹配。
8ulbf1ek2#
你不能在正则表达式
//
表示法中使用变量(没有办法将其与搜索pat
区分开来);你必须指定这个变量是一个带有~
(匹配)运算符的正则表达式。cyej8jka3#
我不明白为什么没有答案提到最明显的解决方案:使用双引号
请注意这会带来代码注入(demonstration (see "Variable within the code"))的风险,但此解决方案适用于@fedorqui的答案福尔斯不足的某些语法。
简单模式(单独)
简单地说:
会成功的
Range Pattern(单独)
这甚至适用于范围模式,而@fedorqui的解决方案则不行。
假设我想匹配
"start #${myid}"
和"end"
之间的所有行,我们可以这样做:Awk完整脚本
现在,使用双引号会破坏一些
awk
功能(例如awk变量,因为它们现在将由shell计算,特别是像$1
这样的字段变量),对于复杂的awk
脚本使用单引号要安全得多(以防止shell解释任何东西)。但是你仍然可以这样绕过去:基本上,您仍然在bash变量周围使用双引号,但在其他地方使用单引号,并将它们连接起来以获得完整的
awk
脚本。wfypjpf44#
这是一种黑客,但它使事情对我来说更简单一点。
首先将其设置为字符串,这样您就可以超越awk的边界来操作它