我需要管理域名(fqdn),将所有域名打印在某个地方,可能在文件 csv 中。所有信息都在apacheconf文件中,我需要将所有域名与ip和端口相关联。 这是示例文件。您可以在服务器名称和服务器别名中使用相同的 FQDN,两个参数之间可能有一些尾随空格,一些注释 (#)。这里是示例文件:
<VirtualHost 10.11.12.21:80>
ServerName host-6.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.21:80>
ServerName www.example.com
ServerAlias www.example.com
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/www.example.com/www.example.com_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.21:80>
ServerName gimbo.customexample.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/gimbo.customexample.org/gimbo.customexample.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:80>
ServerName host-6.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:443>
ServerName host-6.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_ssl_access_log 86400" customssl
IncludeOptional conf.d/star_mydomain_example_org.cnf
</VirtualHost>
<VirtualHost 10.11.12.22:8080>
ServerName host-6.mydomain.example.org
ServerAlias www.example.org www.pollo.biz www.pollone.mondo
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-6.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:80>
ServerName host-7.mydomain.example.org
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-7.mydomain.example.org/host-7.mydomain.example.org_access_log 86400" customssl
</VirtualHost>
<VirtualHost 10.11.12.22:443>
ServerName host-7.mydomain.example.org
ErrorLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-7.mydomain.example.org/host-7.mydomain.example.org_ssl_error_log 86400"
CustomLog "|/usr/sbin/rotatelogs /etc/httpd/logs/host-7.mydomain.example.org/host-7.mydomain.example.org_ssl_access_log 86400" customssl
IncludeOptional conf.d/star_mydomain_example_org.cnf
</VirtualHost>
这些是域名 (fqdn)
gimbo.customexample.org
host-6.mydomain.example.org
host-7.mydomain.example.org
www.example.biz
www.example.com
www.example.org
www.pollo.biz
www.pollone.mondo
我需要这个输出:
host-6.mydomain.example.org,10.11.12.21,80
www.example.com,10.11.12.21,80
www.example.com,10.11.12.21,80
www.example.biz,10.11.12.21,80
gimbo.customexample.org,10.11.12.21,80
host-6.mydomain.example.org,10.11.12.22,80
host-6.mydomain.example.org,10.11.12.22,443
host-6.mydomain.example.org,10.11.12.22,8080
www.example.org,10.11.12.22,8080
www.pollo.biz,10.11.12.22,8080
www.pollone.mondo,10.11.12.22,8080
host-7.mydomain.example.org,10.11.12.22,80
host-7.mydomain.example.org,10.11.12.22,443
我尝试过的:
awk -v n=2 -e '/^\s*Server(Name|Alias)/ { for (i=n; i<=NF; i++) printf "%s%s", $i, (i<NF ? OFS : ORS)}' $1 | awk -v RS='[\n ]' '{print}'
现在我可以打印所有的 FQDN。 如何添加正确的 IP 地址和端口?
使用任何 awk:
$ cat tst.awk
BEGIN { OFS="," }
$1 == "<VirtualHost" {
split($2,tmp,/:/)
ip = tmp[1]
port = tmp[2]+0
}
$1 ~ /^Server(Name|Alias)$/ {
for ( i=2; i<=NF; i++ ) {
fqdns[$i]
}
}
$1 == "</VirtualHost>" {
for ( fqdn in fqdns ) {
print fqdn, ip, port
delete fqdns[fqdn]
}
}
$ awk -f tst.awk file
host-6.mydomain.example.org,10.11.12.21,80
www.example.com,10.11.12.21,80
gimbo.customexample.org,10.11.12.21,80
host-6.mydomain.example.org,10.11.12.22,80
host-6.mydomain.example.org,10.11.12.22,443
host-6.mydomain.example.org,10.11.12.22,8080
www.pollo.biz,10.11.12.22,8080
www.pollone.mondo,10.11.12.22,8080
www.example.org,10.11.12.22,8080
host-7.mydomain.example.org,10.11.12.22,80
host-7.mydomain.example.org,10.11.12.22,443
假设@Grobu 的答案更加优雅(而且可能也更有效),以下也应该达到目的:
grep "\(<VirtualHost \|ServerName \|ServerAlias \)" sample.input \
| sed ':a;N;s/\nServerAlias / / ; ba' \
| sed 's/\(<VirtualHost \|ServerName \)//;s/:\(.*\)>/,\1/' \
| sed 's/ /\n/g' \
| while read line; do if [[ "$line" =~ .+,.+ ]]; then address=$line; else echo "$line,$address"; fi; done
...哪里:
第 1 行 --> 使用 grep 仅提取 VirtualHost、ServerName 和 ServerAlias 行。它产生:
<VirtualHost 10.11.12.21:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.21:80>
ServerName www.example.com
ServerAlias www.example.com
<VirtualHost 10.11.12.21:80>
ServerName gimbo.customexample.org
<VirtualHost 10.11.12.22:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:8080>
ServerName host-6.mydomain.example.org
ServerAlias www.example.org www.pollo.biz www.pollone.mondo
<VirtualHost 10.11.12.22:80>
ServerName host-7.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-7.mydomain.example.org
第 2 行 --> 使用 sed 通过在该行上设置标签 (
:a;
) 来评估一行,并在下一个标签后附加 '
'(N;
),找到替换“
ServerAlias " 带有一个简单的空格 (s/\nServerAlias / / ;
),最后通过跳回到标签 a (ba
) 来重新启动评估。它会产生:
<VirtualHost 10.11.12.21:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.21:80>
ServerName www.example.com www.example.com
<VirtualHost 10.11.12.21:80>
ServerName gimbo.customexample.org
<VirtualHost 10.11.12.22:80>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-6.mydomain.example.org
<VirtualHost 10.11.12.22:8080>
ServerName host-6.mydomain.example.org www.example.org www.pollo.biz www.pollone.mondo
<VirtualHost 10.11.12.22:80>
ServerName host-7.mydomain.example.org
<VirtualHost 10.11.12.22:443>
ServerName host-7.mydomain.example.org
第 3 行 --> 删除所有出现的 ServerName 和 VirtualHost (
s/\(<VirtualHost \|ServerName \)//
),将 ':' 替换为 ',',并删除最后的 '>' (s/:\(.*\)>/,\1/
)。它产生:
10.11.12.21,80
host-6.mydomain.example.org
10.11.12.21,80
www.example.com www.example.com
10.11.12.21,80
gimbo.customexample.org
10.11.12.22,80
host-6.mydomain.example.org
10.11.12.22,443
host-6.mydomain.example.org
10.11.12.22,8080
host-6.mydomain.example.org www.example.org www.pollo.biz www.pollone.mondo
10.11.12.22,80
host-7.mydomain.example.org
10.11.12.22,443
host-7.mydomain.example.org
第 4 行 --> 使用 sed 命令将每个空格替换为新行(
s/ /\n/g
),以便在不同行上获取不同的服务器名称/别名。它产生:
10.11.12.21,80
host-6.mydomain.example.org
10.11.12.21,80
www.example.com
www.example.com
10.11.12.21,80
gimbo.customexample.org
10.11.12.22,80
host-6.mydomain.example.org
10.11.12.22,443
host-6.mydomain.example.org
10.11.12.22,8080
host-6.mydomain.example.org
www.example.org
www.pollo.biz
www.pollone.mondo
10.11.12.22,80
host-7.mydomain.example.org
10.11.12.22,443
host-7.mydomain.example.org
第 5 行 --> 使用 while-do 循环迭代每一行(
while read line; do ...done
),当将一行与 ip 和 port 匹配时临时存储(唯一包含逗号的行:if [[ "$line" =~ .+,.+ ]]; then address=$line;
)而不打印它,否则通过连接存储的 ip 和端口来打印每隔一行 (else echo "$line,$address";
)。最终产生:
host-6.mydomain.example.org,10.11.12.21,80
www.example.com,10.11.12.21,80
www.example.com,10.11.12.21,80
gimbo.customexample.org,10.11.12.21,80
host-6.mydomain.example.org,10.11.12.22,80
host-6.mydomain.example.org,10.11.12.22,443
host-6.mydomain.example.org,10.11.12.22,8080
www.example.org,10.11.12.22,8080
www.pollo.biz,10.11.12.22,8080
www.pollone.mondo,10.11.12.22,8080
host-7.mydomain.example.org,10.11.12.22,80
host-7.mydomain.example.org,10.11.12.22,443