如何匹配awk中变量中给定的模式? [英] How to match a pattern given in a variable in awk?

查看:38
本文介绍了如何匹配awk中变量中给定的模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从管道分隔文件中提取一个存在特定模式的子字符串,因此我使用了下面的命令,

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?

解决方案

如果想通过变量提供模式,需要使用~来匹配:

awk -v pat="$pattern";'$0 ~ 拍'


就您而言,问题与 -F 无关.

问题是当您希望 pat 成为变量时使用了 /pat/.如果您说/pat/awk 会将其理解为文字pat",因此它会尝试匹配包含字符串pat"的那些行.>

总的来说,您的代码应该是:

awk -v pat="$pattern";-F:"'$0~pat{print $1, $2, $3, $4 }' 文件#^^^^^^


看一个例子:

给定这个文件:

$ cat 文件你好这是一个变量你好再见

让我们寻找包含hello"的行:

$ awk '/hello/' 文件你好你好再见

现在让我们尝试按照您的方式查找包含在变量中的pat":

$ awk -v pat=你好"'/pat/' 文件$ # 没有匹配项!

现在让我们使用 $0 ~ pat 表达式:

$ awk -v pat=你好"'$0~pat' 文件你好#我们匹配!你好再见


当然,您可以使用这样的表达式来匹配一个字段并说 awk -v pat=$pattern";'$2 ~ pat' 文件 等等.

来自 GNU Awk 用户指南 → 3.1 如何使用正则表达式:

<块引用>

当正则表达式包含在斜杠中时,例如/foo/,我们称其为正则表达式常量,很像 5.27 是数字常量,而foo"则为正则表达式常量.是一个字符串常量.

GNU Awk 用户指南 → 3.6 使用动态正则表达式:

<块引用>

‘~’或‘!~’运算符的右侧不必是正则表达式常量(即斜杠之间的字符串).它可能是任何表达.如果表达式被计算并转换为字符串必要的;然后将字符串的内容用作正则表达式.一种以这种方式计算的正则表达式称为动态正则表达式或计算正则表达式:

BEGIN {digits_regexp = "[[:digit:]]+";}$0 ~digits_regexp { 打印}

这将digits_regexp设置为描述一个或多个数字的正则表达式,并测试输入记录是否与此正则表达式匹配.

I want to extract a substring where certain pattern exist from pipe separated file, thus I used below command,

awk -F ":" '/REWARD REQ. SERVER HEADERS/{print $1, $2, $3, $4}' sample_profile.txt

Here, 'REWARD REQ. SERVER HEADERS' is a pattern which is to be searched in the file, and print its first 4 parts on a colon separated line.

Now, I want to send bash variable to act as a pattern. thus I used below command, but it's not working.

awk -v pat="$pattern" -F ":" '/pat/{print $1, $2 , $3, $4 } sample_profile.txt

How can I use -v and -F in a single awk command?

解决方案

If you want to provide the pattern through a variable, you need to use ~ to match against it:

awk -v pat="$pattern" '$0 ~ pat'


In your case, the problem does not have to do with -F.

The problem is the usage of /pat/ when you want pat to be a variable. If you say /pat/, awk understands it as a literal "pat", so it will try to match those lines containing the string "pat".

All together, your code should be:

awk -v pat="$pattern" -F ":" '$0~pat{print $1, $2, $3, $4 }' file
#                             ^^^^^^


See an example:

Given this file:

$ cat file
hello
this is a var
hello bye

Let's look for lines containing "hello":

$ awk '/hello/' file
hello
hello bye

Let's now try looking for "pat", contained in a variable, the way you were doing it:

$ awk -v pat="hello" '/pat/' file
$                                    # NO MATCHES!

Let's now use the $0 ~ pat expression:

$ awk -v pat="hello" '$0~pat' file
hello                                 # WE MATCH!
hello bye


Of course, you can use such expressions to match just one field and say awk -v pat="$pattern" '$2 ~ pat' file and so on.

From GNU Awk User's Guide → 3.1 How to Use Regular Expressions:

When a regexp is enclosed in slashes, such as /foo/, we call it a regexp constant, much like 5.27 is a numeric constant and "foo" is a string constant.

And GNU Awk User's Guide → 3.6 Using Dynamic Regexps:

The righthand side of a ‘~’ or ‘!~’ operator need not be a regexp constant (i.e., a string of characters between slashes). It may be any expression. The expression is evaluated and converted to a string if necessary; the contents of the string are then used as the regexp. A regexp computed in this way is called a dynamic regexp or a computed regexp:

BEGIN { digits_regexp = "[[:digit:]]+" }
$0 ~ digits_regexp    { print }

This sets digits_regexp to a regexp that describes one or more digits, and tests whether the input record matches this regexp.

这篇关于如何匹配awk中变量中给定的模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆