Bash 和 awk - 在进行多行模式数学运算时如何将变量传递给 awk?
Bash and awk - how to pass a variable to awk when doing multiline pattern maths?
我正在使用 AWK
进行多行模式匹配。
示例:
awk '/"ip": /,/"id": /'
我想在知道 ip
时将参数传递给 AWK,以便它 return 包含指定 IP 的行。示例:
awk '/"ip": "$IP"/,/"id": /'
有什么方法可以做到这一点?
我试过:
awk '/"ip": "$IP"/,/"id": /'
awk '/"ip": "${IP}"/,/"id": /'
awk "/\"ip\": \"$IP\"/,/\"id'\": /"
我想知道如何将这种方法用于模式:
var="hello"; awk -v a="$var"
谢谢。
回答
- 已接受并可在下方找到。
有关如何使匹配更精确(使用变量 + 字符串模式)感兴趣的任何人的其他详细信息。请注意,您不能用双引号将正在使用的变量包装在模式中,即使引号被转义也不会起作用:
cat l.txt | awk '[=15=] ~ "\"ip\": \"103.6.181.43", [=15=] ~ "\"id\": \""' ===> works
cat l.txt | awk -v ipvar=103.6.181.43 '[=15=] ~ ipvar, [=15=] ~ "\"id\": \""' ===> works
cat l.txt | awk -v ipvar=103.6.181.43 '[=15=] ~ "\"ip\": \"ipvar", [=15=] ~ "\"id\": \""' ===> does not work
cat l.txt | awk -v ipvar=103.6.181.43 '[=15=] ~ "\"ip\": \""ipvar, [=15=] ~ "\"id\": \""' ===> works
最后,您可以包装/包围qoutes中使用的参数。比较:
awk -v ipvar=103.6.181.43 '[=16=] ~ "\"ip\": \"ipvar\"", [=16=] ~ "\"id\": \""' ===> will not work
awk -v ipvar=103.6.181.43 '[=16=] ~ "\"ip\": \""ipvar"\"", [=16=] ~ "\"id\": \""' ===> will work and is equivalent.
您正在尝试扩展单引号内的变量。单引号 (') 使它们之间的所有内容都按字面意义被 bash 引用。尝试改用双引号,并查看 Quotes.
关于您关于 awk
作业的问题,这里有一个例子:
awk -v foo="bar" 'foo ~ [=11=]' <<< $'foo\nbar\nbaz'
输出:bar
.
不要在 / /
内添加变量,因为那里有一个正则表达式。
请改用 [=15=] ~ pattern
,这会给您更多的自由。毕竟
/pattern1/,/pattern2
与
相同
[=11=] ~ pattern1, [=11=] ~ pattern2
因此您可以使用 -v
提供值并说:
awk -v var="$bash_variable" '[=12=]~"ip: " var,[=12=] ~ "id: " var'
# ^^^^^^^^^^^^^
# ^^^^^^^^^^^^^^^
# start end
测试
$ cat a
hello
ip: 23
bye
and this is
id: 23
hehe
done
$ awk -v var=23 '[=13=]~"ip: " var,/id: /' a
ip: 23
bye
and this is
id: 23
我正在使用 AWK
进行多行模式匹配。
示例:
awk '/"ip": /,/"id": /'
我想在知道 ip
时将参数传递给 AWK,以便它 return 包含指定 IP 的行。示例:
awk '/"ip": "$IP"/,/"id": /'
有什么方法可以做到这一点?
我试过:
awk '/"ip": "$IP"/,/"id": /'
awk '/"ip": "${IP}"/,/"id": /'
awk "/\"ip\": \"$IP\"/,/\"id'\": /"
我想知道如何将这种方法用于模式:
var="hello"; awk -v a="$var"
谢谢。
回答
- 已接受并可在下方找到。
有关如何使匹配更精确(使用变量 + 字符串模式)感兴趣的任何人的其他详细信息。请注意,您不能用双引号将正在使用的变量包装在模式中,即使引号被转义也不会起作用:
cat l.txt | awk '[=15=] ~ "\"ip\": \"103.6.181.43", [=15=] ~ "\"id\": \""' ===> works cat l.txt | awk -v ipvar=103.6.181.43 '[=15=] ~ ipvar, [=15=] ~ "\"id\": \""' ===> works cat l.txt | awk -v ipvar=103.6.181.43 '[=15=] ~ "\"ip\": \"ipvar", [=15=] ~ "\"id\": \""' ===> does not work cat l.txt | awk -v ipvar=103.6.181.43 '[=15=] ~ "\"ip\": \""ipvar, [=15=] ~ "\"id\": \""' ===> works
最后,您可以包装/包围qoutes中使用的参数。比较:
awk -v ipvar=103.6.181.43 '[=16=] ~ "\"ip\": \"ipvar\"", [=16=] ~ "\"id\": \""' ===> will not work
awk -v ipvar=103.6.181.43 '[=16=] ~ "\"ip\": \""ipvar"\"", [=16=] ~ "\"id\": \""' ===> will work and is equivalent.
您正在尝试扩展单引号内的变量。单引号 (') 使它们之间的所有内容都按字面意义被 bash 引用。尝试改用双引号,并查看 Quotes.
关于您关于 awk
作业的问题,这里有一个例子:
awk -v foo="bar" 'foo ~ [=11=]' <<< $'foo\nbar\nbaz'
输出:bar
.
不要在 / /
内添加变量,因为那里有一个正则表达式。
请改用 [=15=] ~ pattern
,这会给您更多的自由。毕竟
/pattern1/,/pattern2
与
相同[=11=] ~ pattern1, [=11=] ~ pattern2
因此您可以使用 -v
提供值并说:
awk -v var="$bash_variable" '[=12=]~"ip: " var,[=12=] ~ "id: " var'
# ^^^^^^^^^^^^^
# ^^^^^^^^^^^^^^^
# start end
测试
$ cat a
hello
ip: 23
bye
and this is
id: 23
hehe
done
$ awk -v var=23 '[=13=]~"ip: " var,/id: /' a
ip: 23
bye
and this is
id: 23