我有一个工作命令
awk -F '[)#/(:]' 'BEGIN { fw="";dev=""} {if ($0~/sh failover/) fw=$1 ; if (($0~/This host/)||($0~/Other host/)) dev=$2; if ($0~/\)\:/) {print $2,$1,fw, dev} }' OFS="|" test_data
我想把它变成一个脚本。当这样做时...
#!/bin/sh
awk '
BEGIN {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""}
{
if ($0~/sh failover/) fw=$1 ;
if (($0~/This host/)||($0~/Other host/)) dev=$2;
if ($0~/\)\:/) {
print $2,$1,fw, dev
}
}' test_data
...F='[)#/(:]' 会导致错误。
[...srv01]$ ./test
./test: line 3: syntax error near unexpected token `)'
./test: line 3: `BEGIN {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""} '
[...srv01]$
更改为双引号时,它将 twp 双引号之间的所有内容作为分隔符,因此将查找 )#/(: 而不是)或者#或者/或者(或者:
这是test_data的文件内容
[...srv01]$ cat test_data
JoeASA# sh failover | i \)\:|host
This host: Primary - Active
admin Interface management (313.13.0.13): Normal (Monitored)
DMZ-FW Interface Inside (310.13.19.7): Normal (Not-Monitored)
DMZ-FW Interface Outside-Zone2 (912.168.119.7): Normal (Not-Monitored)
ENET Interface OUTSIDE(912.168.191.7): Normal (Not-Monitored)
ENET Interface dmarc (912.168.192.7): Normal (Not-Monitored)
GW Interface Extranet (912.168.23.27): Normal (Not-Monitored)
GW Interface Outside-Zone (912.168.123.27): Normal (Not-Monitored)
GW Interface management (331.1.1.47): Normal (Not-Monitored)
Other host: Secondary - Standby Ready
admin Interface management (313.13.0.12): Normal (Monitored)
DMZ-FW Interface Inside (310.13.19.6): Normal (Not-Monitored)
DMZ-FW Interface Outside-Zone2 (912.168.119.6): Normal (Not-Monitored)
ENET Interface OUTSIDE(912.168.191.6): Normal (Not-Monitored)
ENET Interface dmarc (912.168.192.6): Normal (Not-Monitored)
GW Interface Extranet (912.168.23.26): Normal (Not-Monitored)
GW Interface Outside-Zone (912.168.123.26): Normal (Not-Monitored)
GW Interface management (331.1.1.46): Normal (Not-Monitored)
SIMPLEASA1/sec/act# sh failover | i \)\:|host
This host: Secondary - Active
Interface Edge (912.168.22.17): Normal (Monitored)
Interface Inside (310.13.19.17): Normal (Monitored)
Interface EXT (912.168.50.17): Normal (Monitored)
Interface WIFI (912.168.11.17): Normal (Monitored)
Other host: Primary - Standby Ready
Interface Edge (912.168.22.16): Normal (Monitored)
Interface Inside (310.13.19.16): Normal (Monitored)
Interface EXT (912.168.50.16): Normal (Monitored)
Interface WIFI (912.168.11.16): Normal (Monitored)
[..srv01]$
答案1
您将脚本作为单引号字符串从 shell 传递给 awk,但您似乎有单引号里面剧本也是如此。他们实际上结束了引用的字符串:
awk 'BEGIN {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""}
^^^^^^^ not quoted
shell 看到一个不带引号的)
,这会导致语法错误。无论如何,您不想在 awk 脚本中使用单引号,它们将是语法错误在 awk 中。因此,请使用双引号,就像您对其他赋值所做的那样,它们很好地适合 shell 中的单引号,并且实际上可以在 awk 代码中工作:
awk 'BEGIN { foo="bar"; ...}'
然后,请注意-F
awk 的选项的作用是设置字段分隔符,它是变量FS
,而不是F
。因此,您想要拥有BEGIN { FS="[)#/(:]"; ...
,并且您可能也不想更改默认的记录分隔符RS
- 至少您没有在上面的一行中更改它。
另外,您可以跳过 shell,直接使 awk 成为该脚本的解释器(假设您的 awk 位于/usr/bin/awk
),而不是将 awk 脚本放入 shell 脚本中:
#!/usr/bin/awk -f
BEGIN { FS="[)#/(:]"; OFS="|"; fw=""; dev=""}
{
if ( $0 ~ /sh failover/ ) fw=$1 ;
if (($0 ~ /This host/) || ($0 ~ /Other host/)) dev=$2;
if ( $0 ~ /\)\:/ ) {
print $2, $1, fw, dev
}
}
如果它被调用./script.awk
并可执行,那么您可以将其运行为./script.awk filename
,即使用要处理的文件作为脚本的参数。