我能够使用 awk 表达式捕获括号之间的所有值
'NR>1{print $1}' RS='(' FS=')'
但我很难具体匹配一个,我不想按行号匹配,而是按字符串匹配。不确定 awk 是否可以做到这一点。
原始文件内容为
if ($remote_addr ~ ^(1.2.3.4|5.6.7.8)$) {
set $maintenance off;
}
if ($maintenance = on) {
return 503;
}
其中有多个不同顺序的括号。
我需要1.2.3.4|5.6.7.8
从该行中提取内容
if ($remote_addr ~ ^
(或者只是在包含 的行中$remote_addr
)。
答案1
因为它是单行上的简单替换,所以我只使用 sed 来实现:
$ sed -n 's/.*$remote_addr[^(]*(\([^)]*\).*/\1/p' file
1.2.3.4|5.6.7.8
如果您确实想使用 awk,那么您可以使用任何 awk 来执行此操作:
$ awk 'sub(/.*\$remote_addr[^(]*\(/,"") && sub(/).*/,"")' file
1.2.3.4|5.6.7.8
答案2
考虑到您要提取的内容内括号内的语句if ($remote_addr ~ ( ... ) )
,下面的awk
程序应该:
awk 'index($0,"$remote_addr"){sub(/^.*\(/,"");sub(/\).+$/,"");print}' inputfile
这将匹配包含字符串的行$remote_addr
。在该行中,它将删除从行首到最后一行的所有内容(
,以及从第一行)
到行尾的所有内容。然后它会打印该行的剩余值。
答案3
你也可以尝试这个sed
sed -En '/\$remote_addr/ s/.*\(([0-9.]*\|[0-9.]*)\).*/\1/p' $file
它将匹配任何行,$remote_addr
然后提取匹配项。
代码应该能够在不事先显式匹配的情况下匹配模式$remote_addr
。
sed -En 's/.*\(([0-9.]*\|[0-9.]*)\).*/\1/p' $file
输出
1.2.3.4|5.6.7.8
答案4
awk '/\$remote_addr/{for(i=1;i<=NF;i++){if($i ~ /\([0-9].*|[0-9].*\)/){print $i}}}' filename|awk -F "(" '{gsub(/\).*/,"",$2);print $2}
输出
1.2.3.4|5.6.7.8