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.
在这里,“奖励申请。服务器头是一个在文件中搜索的模式,并在一个冒号分隔的线上打印前4个部分。
Now, I want to send bash variable to act as a pattern. thus I used below command, but it's not working.
现在,我想发送bash变量作为一个模式。因此,我使用了下方命令,但它不起作用。
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?
如何在一个awk命令中使用-v和-F ?
3 个解决方案
#1
18
The problem here does not have to do with -F
.
这里的问题与-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".
问题是当你想让pat成为变量时/pat/的用法。如果您输入/pat/, awk将其理解为一个字面的“pat”,因此它将尝试匹配包含字符串“pat”的行。
If you want to provide the pattern through a variable, you need to use ~
as this:
如果您想通过变量提供模式,您需要使用~
awk -v pat="$pattern" '$0 ~ 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":
让我们寻找包含“hello”的行:
$ awk '/hello/' file
hello
hello bye
Let's now try looking for "pat", contained in a variable, the way you were doing it:
现在,让我们尝试寻找包含在变量中的“pat”,看看您是怎么做的:
$ awk -v pat="hello" '/pat/' file
$ # NO MATCHES!
Let's now use the $0 ~ pat
expression:
现在我们使用$0 ~ pat表达式:
$ 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.
当然,您可以使用这样的表达式来匹配一个字段,比如awk -v pat=“$pattern”“$2 ~ pat”文件等等。
From GNU Awk User's Guide → 3.1 How to Use Regular Expressions:
从GNU Awk用户指南→3.1如何使用正则表达式:
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.
当regexp包含在斜线中(如/foo/)时,我们将它称为regexp常量,就像5.27是一个数值常量,而“foo”是一个字符串常量。
And GNU Awk User's Guide → 3.6 Using Dynamic Regexps:
用户指南和GNU Awk→3.6使用动态regexp:
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:
“~”或“!”的右手边。~ '运算符不必是regexp常数(即。,斜线之间的一串字符)。它可以是任何一种表达。如果需要,表达式将被计算并转换为字符串;然后将字符串的内容用作regexp。以这种方式计算的regexp称为动态regexp或计算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.
这将digits_regexp设置为regexp,该regexp描述一个或多个数字,并测试输入记录是否与该regexp匹配。
#2
4
awk -v pat="$pattern" -F":" '$0 ~ pat { print $1, $2, $3, $4 }' sample_profile.txt
You can't use the variable inside the regex //
notation (there's no way to distinguish it from searching for pat
); you have to specify that the variable is a regex with the ~
(matching) operator.
您不能使用regex //符号内的变量(没有办法区分它与搜索pat);您必须指定该变量是具有~(匹配)操作符的regex。
#3
0
This is kind of a hack but it makes things a little simpler for me.
这是一种技巧,但对我来说更简单。
cmd="awk '/$pattern/'"
eval $cmd
making it a string first lets you manipulate it past the boundaries of awk
使它成为一个字符串首先允许您操作它通过awk的边界
#1
18
The problem here does not have to do with -F
.
这里的问题与-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".
问题是当你想让pat成为变量时/pat/的用法。如果您输入/pat/, awk将其理解为一个字面的“pat”,因此它将尝试匹配包含字符串“pat”的行。
If you want to provide the pattern through a variable, you need to use ~
as this:
如果您想通过变量提供模式,您需要使用~
awk -v pat="$pattern" '$0 ~ 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":
让我们寻找包含“hello”的行:
$ awk '/hello/' file
hello
hello bye
Let's now try looking for "pat", contained in a variable, the way you were doing it:
现在,让我们尝试寻找包含在变量中的“pat”,看看您是怎么做的:
$ awk -v pat="hello" '/pat/' file
$ # NO MATCHES!
Let's now use the $0 ~ pat
expression:
现在我们使用$0 ~ pat表达式:
$ 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.
当然,您可以使用这样的表达式来匹配一个字段,比如awk -v pat=“$pattern”“$2 ~ pat”文件等等。
From GNU Awk User's Guide → 3.1 How to Use Regular Expressions:
从GNU Awk用户指南→3.1如何使用正则表达式:
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.
当regexp包含在斜线中(如/foo/)时,我们将它称为regexp常量,就像5.27是一个数值常量,而“foo”是一个字符串常量。
And GNU Awk User's Guide → 3.6 Using Dynamic Regexps:
用户指南和GNU Awk→3.6使用动态regexp:
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:
“~”或“!”的右手边。~ '运算符不必是regexp常数(即。,斜线之间的一串字符)。它可以是任何一种表达。如果需要,表达式将被计算并转换为字符串;然后将字符串的内容用作regexp。以这种方式计算的regexp称为动态regexp或计算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.
这将digits_regexp设置为regexp,该regexp描述一个或多个数字,并测试输入记录是否与该regexp匹配。
#2
4
awk -v pat="$pattern" -F":" '$0 ~ pat { print $1, $2, $3, $4 }' sample_profile.txt
You can't use the variable inside the regex //
notation (there's no way to distinguish it from searching for pat
); you have to specify that the variable is a regex with the ~
(matching) operator.
您不能使用regex //符号内的变量(没有办法区分它与搜索pat);您必须指定该变量是具有~(匹配)操作符的regex。
#3
0
This is kind of a hack but it makes things a little simpler for me.
这是一种技巧,但对我来说更简单。
cmd="awk '/$pattern/'"
eval $cmd
making it a string first lets you manipulate it past the boundaries of awk
使它成为一个字符串首先允许您操作它通过awk的边界