use*_*472 5 awk text-processing nginx
我们如何使用 AWK 提取 nginx 服务器块?输入
server { # php/fastcgi
listen 80;
server_name domain1.com www.domain1.com;
access_log logs/domain1.access.log main;
root html;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:1025;
}
}
server { # simple reverse-proxy
listen 80;
server_name domain2.com www.domain2.com;
access_log logs/domain2.access.log main;
# serve static files
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
root /var/www/virtual/big.server.com/htdocs;
expires 30d;
}
# pass requests for dynamic content to rails/turbogears/zope, et al
location / {
proxy_pass http://127.0.0.1:8080;
}
}
Run Code Online (Sandbox Code Playgroud)
我们如何匹配所需的值并为每个 server{} 块打印一行?
例如
我需要获取listen|root|server_name 的值。所需的输出是
80 domain1.com www.domain1.com html
80 domain2.com www.domain2.com /var/www/virtual/big.server.com/htdocs
Run Code Online (Sandbox Code Playgroud)
由于每行可以有多个以空格分隔的值,因此使用起来awk有点棘手。这在 awk 中是绝对可能的,但使用 Perl 之类的东西更简单:
$ perl -lne '
if(/(^| )server / || eof){
print join " ",@ll if $ll[0];
@ll=();
}
/^(listen|root|server_name)\s+(\S[^;]+)/ && push @ll,$2' file
80 domain1.com www.domain1.com html
80 domain2.com www.domain2.com /var/www/virtual/big.server.com/htdocs
Run Code Online (Sandbox Code Playgroud)
的-lne手段“逐行读取输入文件中的行(-n),剥离后换行和一个换行添加到每个print呼叫(-l)和运行由下式给出的脚本-e每行”。
编码:
if(/(^| )server / || eof){ : 如果当前行包含server由空格包围或在行首的单词,则此部分将运行。
print join " ",@ll if $ll[0]; : 如果当前数组中存储了任何内容@ll(因此,如果$ll[0]定义了数组的第一个元素 , ),则打印以空格连接的数组内容。
@ll=(); : 清空数组,以便我们可以获取下一个服务器的信息。
/^(listen|root|server_name)\s+(\S[^;]+)/ && push @ll,$2': 如果这一行以关键字之一开头,然后有一个或多个空白字符,则找到第一个非空白字符和尽可能多的非;字符,直到行尾并添加它(括号将捕获模式所以“这个”现在是$2) 到阵列@ll进行打印。
这是在 awk 中执行此操作的(丑陋)方式:
$ awk '
(/ server\s*\{/){
if(out){
print out
}
out=""
}
($1=="listen" || $1=="root" || $1=="server_name"){
gsub(";","");
$1="";
gsub(/^ */,"");
out ? out=out" "$0 : out=$0
}
END{print out}' file
80 domain1.com www.domain1.com html
80 domain2.com www.domain2.com /var/www/virtual/big.server.com/htdocs
Run Code Online (Sandbox Code Playgroud)