为什么 awk 连接不同行的字符串

为什么 awk 连接不同行的字符串

再会。

我正在尝试在从 /etc/resolv.conf.dnsph 中提取的 IPv6 地址上运行 ping6。不过,看起来好像 awk 将 IPv6 地址串到一行上。

$ grep ^nameserver /etc/resolv.conf.dnsph |awk '{print $2}'
2001:1890:1001:2224::1
2001:1890:1001:2424::1
$ ping6 $(grep ^nameserver /etc/resolv.conf.dnsph |awk '{print $2}')
ping6: Source routing is deprecated by RFC5095.
Usage: ping6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
             [-l preload] [-m mark] [-M pmtudisc_option]
             [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
             [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
             [-W timeout] destination
$ echo $(grep ^nameserver /etc/resolv.conf.dnsph |awk '{print $2}')
2001:1890:1001:2224::1 2001:1890:1001:2424::1

添加“END {printf“\n”}”没有任何区别:

$ ping6 $(awk '/^nameserver/ {print $2}; END {printf "\n"}' /etc/resolv.conf.dnsph)
ping6: Source routing is deprecated by RFC5095.
Usage: ping6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
             [-l preload] [-m mark] [-M pmtudisc_option]
             [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
             [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
             [-W timeout] destination
$ echo $(awk '/^nameserver/ {print $2}; END {printf "\n"}' /etc/resolv.conf.dnsph)
2001:1890:1001:2224::1 2001:1890:1001:2424::1

请指教。

比约恩

答案1

当给定多个地址时,ping6将它们解释为用于到达目标(最后一个地址)的跃点。在您的情况下,您需要循环输出:

for ip in $(awk '/^nameserver/ { print $2 }' /etc/resolv.conf.dnsph); do
    ping6 "$ip"
done

AWK 在一行上正确输出每个 IP 地址(如第一个命令中所示),但未加引号命令替换导致换行符被有效删除——它们充当单词之间的分隔符。

答案2

$(...)构造旨在为命令提供命令行参数。命令行参数以空格分隔,而不是换行符,因此 shell 会“优化”输出。但是您可以引用$(...),如下所示:

> echo $(echo 1;echo 2)
1 2
> echo "$(echo 1;echo 2)"
1
2

awk问题仍然与连接线无关(即:它确实不是),但是使用$(...).实际上awk也可以grep使用 来完成这项工作,并且您还可以通过从内部调用 ping 来awk '/^nameserver/ {print $2}' /etc/resolv.conf.dnsph避免 shell循环:forawk

awk '/^nameserver/ { system("ping6 " $2); }' /etc/resolv.conf.dnsph

相关内容