@anthony-briggs 正确地指出,如果您的 server_name ... ; 声明分布在多行中,则此处给出的大多数其他答案都将不起作用。
但是,如果您能负担得起使用perl 口译员的奢侈,您可以将他的解决方案缩短为这个oneliner:
nginx -T | perl -ln0777e '$,=$\; s/^\s*#.*\n//mg; print grep !$u{$_}++ && !m/^_$/, map m/(\S+)/g, m/\bserver_name\s++(.*?)\s*;/sg'
分块:
perl -l -n -0777 -e
-l :使print 命令以换行符终止其输出;
它还会导致在读取每个输入记录时从每个输入记录中删除尾随换行符,但这并不困扰我们,因为我们:
-n -0777:一口气将所有输入输入$_(一条记录);
-e : 简单地执行下一个参数作为 Perl 源代码;
$, = $\ ;
使print 命令也在其每个参数之间输出一个换行符;
s/^\s*#.*\n//mg ;
删除所有cmets;
忽略前导空格,假设 cmets 开始并一直运行到行尾(. 此处不匹配换行符);
m/\bserver_name\s++(.*?)\s*;/sg
在所有 server_name ... ; 声明之间生成所有内容(. 是否在此处匹配换行符);
...都是map-ped to:
map m/(\S+)/g,
...这将只留下连续的非空白块;
...然后 grep-ped 是唯一性,不是是特殊的“_”服务器名称,
grep !$u{$_}++ && !m/^_$/,
...和print-ed(未排序)。