使用awk按行向后搜索,并将结果追加到下一行

使用awk按行向后搜索,并将结果追加到下一行,awk,hosts-file,dnsmasq,Awk,Hosts File,Dnsmasq,我正在尝试生成一个临时主机文件,该文件基于dnsmasq提供的DNS日志。我已经让它大部分工作,但我有一个与CNAMEs的问题。我将展示我迄今所取得的成就 日志中有3种类型的响应,我需要获取它们。最简单的是很容易从日志中提取,例如 Jun 20 14:27:59 dnsmasq[2551]: reply stackoverflow.com is 64.34.119.12 可以使用以下命令将其输出到“64.34.119.12 stackoverflow.com” 另一种类型的日志涉及CNAMEs

我正在尝试生成一个临时主机文件,该文件基于dnsmasq提供的DNS日志。我已经让它大部分工作,但我有一个与CNAMEs的问题。我将展示我迄今所取得的成就

日志中有3种类型的响应,我需要获取它们。最简单的是很容易从日志中提取,例如

Jun 20 14:27:59 dnsmasq[2551]: reply stackoverflow.com is 64.34.119.12
可以使用以下命令将其输出到“64.34.119.12 stackoverflow.com”

另一种类型的日志涉及CNAMEs,这里是一个示例

Jun 20 14:42:11 dnsmasq[2551]: reply www.videolan.org is <CNAME>
Jun 20 14:42:11 dnsmasq[2551]: reply ganesh.videolan.org is 88.191.250.2
但是,此方法不适用于以下类型的日志,其中有多个CNAME

Jun 20 15:00:42 dnsmasq[2551]: reply en.wikipedia.org is <CNAME>                        
Jun 20 15:00:42 dnsmasq[2551]: reply wikipedia-lb.wikimedia.org is <CNAME>              
Jun 20 15:00:42 dnsmasq[2551]: reply wikipedia-lb.esams.wikimedia.org is 91.198.174.225
为了解决这个问题,我相信文件需要向后读取,但是这样做不会弄乱awk的getline部分,从而附加到下一行吗

理想情况下,我希望将这两种类型的日志合并到一个命令中,然后输出所有内容,而不必分别运行这两个脚本。是否有人可以协助修复awk命令以执行此操作

下面是“grep reply/var/dnslog”的示例,以及要输出的所需主机文件。目前还有其他次要问题。这些将在所需主机输出中突出显示

Jun 20 15:28:21 dnsmasq[2551]: reply photos-a.ak.fbcdn.net is <CNAME>
Jun 20 15:28:21 dnsmasq[2551]: reply photos-a.ak.facebook.com.edgesuite.net is <CNAME>
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.25
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.48
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.64
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.9
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.26
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.51
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.8
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.50
Jun 20 15:28:21 dnsmasq[2551]: reply a995.dspmm1.akamai.net is 213.200.108.65
Jun 20 15:28:22 dnsmasq[2551]: reply stackoverflow.com is 64.34.119.12
Jun 20 15:29:41 dnsmasq[2551]: reply www.wikipedia.org is <CNAME>
Jun 20 15:29:41 dnsmasq[2551]: reply wikipedia-lb.wikimedia.org is <CNAME>
Jun 20 15:29:41 dnsmasq[2551]: reply wikipedia-lb.esams.wikimedia.org is 91.198.174.225
Jun 20 15:29:42 dnsmasq[2551]: reply en.wikipedia.org is <CNAME>
Jun 20 15:29:42 dnsmasq[2551]: reply wikipedia-lb.wikimedia.org is <CNAME>
Jun 20 15:29:42 dnsmasq[2551]: reply wikipedia-lb.esams.wikimedia.org is 91.198.174.225
Jun 20 15:29:42 dnsmasq[2551]: reply ja.wikipedia.org is <CNAME>
Jun 20 15:29:42 dnsmasq[2551]: reply wikipedia-lb.wikimedia.org is <CNAME>
Jun 20 15:29:42 dnsmasq[2551]: reply wikipedia-lb.esams.wikimedia.org is 91.198.174.225

其目的是,该文件将在低带宽、高延迟链路上分发,因此该文件应尽可能小。我知道长时间使用此文件会导致很多问题,我已将该文件配置为仅在短时间内有效。如果有人能帮助解决所指出的问题,我们将不胜感激。此外,我有一个有限的UNIX应用程序可用范围。如果可以在awk中实现上述功能,则更可取。提前谢谢你

awk
排序一起使用

..|awk '{if($8 ~ /<CNAME>/){load=load" "$6}else{print $8" "load" "$6;load=""}}'
  | sort -u -k2
。| awk'{if($8~/){load=load”“$6}else{print$8”“load”“$6;load=”“}
|排序-u-k2

awk
排序一起使用

..|awk '{if($8 ~ /<CNAME>/){load=load" "$6}else{print $8" "load" "$6;load=""}}'
  | sort -u -k2
。| awk'{if($8~/){load=load”“$6}else{print$8”“load”“$6;load=”“}
|排序-u-k2

使用
awk-f parse.awk dnsmasq.log调用

/reply/ { 
    host = $6;
    ip = $8;

    names[length(names)+1] = host;

    if (ip !~ /CNAME/) {
    # assign all names up to now the same IP
    # This will overwrite any previous IP assignment as well
    for (i in names) IPs[names[i]] = ip;
    delete names;
    }
}

END {
    # collate hostnames for a particular IP
    for (host in IPs) hosts[IPs[host]] = hosts[IPs[host]]" "host;
    for (IP in hosts) print IP hosts[IP];
}

使用
awk-f parse.awk dnsmasq.log调用

/reply/ { 
    host = $6;
    ip = $8;

    names[length(names)+1] = host;

    if (ip !~ /CNAME/) {
    # assign all names up to now the same IP
    # This will overwrite any previous IP assignment as well
    for (i in names) IPs[names[i]] = ip;
    delete names;
    }
}

END {
    # collate hostnames for a particular IP
    for (host in IPs) hosts[IPs[host]] = hosts[IPs[host]]" "host;
    for (IP in hosts) print IP hosts[IP];
}

非常感谢你!我正在使用的设备没有sort命令,但我使用了“|awk'!x[$2]+'”来修复它。这在效率等方面可以吗?是否也可以合并大部分重复的行,例如示例中给出的wikipedia示例?非常感谢!我正在使用的设备没有sort命令,但我使用了“|awk'!x[$2]+'”来修复它。这在效率等方面可以吗?是否也可以合并大部分重复的行,例如示例中给出的wikipedia示例?谢谢
213.200.108.26  a995.dspmm1.akamai.net photos-a.ak.facebook.com.edgesuite.net photos-a.ak.fbcdn.net 
##ideally select 1 host at random from multiple of a995.dspmm1.akamai.net, although list may be randomised already so 1st will suffice##
64.34.119.12    stackoverflow.com
91.198.174.225  wikipedia-lb.esams.wikimedia.org wikipedia-lb.wikimedia.org www.wikipedia.org
91.198.174.225  wikipedia-lb.esams.wikimedia.org wikipedia-lb.wikimedia.org en.wikipedia.org
91.198.174.225  wikipedia-lb.esams.wikimedia.org wikipedia-lb.wikimedia.org ja.wikipedia.org 
##Ideally, detect these similarities for wikipedia and convert the 3 lines into this;##
91.198.174.225  wikipedia-lb.esams.wikimedia.org wikipedia-lb.wikimedia.org www.wikipedia.org en.wikipedia.org ja.wikipedia.org
..|awk '{if($8 ~ /<CNAME>/){load=load" "$6}else{print $8" "load" "$6;load=""}}'
  | sort -u -k2
/reply/ { 
    host = $6;
    ip = $8;

    names[length(names)+1] = host;

    if (ip !~ /CNAME/) {
    # assign all names up to now the same IP
    # This will overwrite any previous IP assignment as well
    for (i in names) IPs[names[i]] = ip;
    delete names;
    }
}

END {
    # collate hostnames for a particular IP
    for (host in IPs) hosts[IPs[host]] = hosts[IPs[host]]" "host;
    for (IP in hosts) print IP hosts[IP];
}