Использование awk для поиска назад по строке и добавления результата к следующей строке
Я пытаюсь создать временный файл hosts, который основан на журнале DNS, предоставленном dnsmasq. У меня это в основном работает, но у меня проблема с CNAME. Я покажу, чего я достиг до сих пор.
В журнале есть 3 типа ответов, которые мне нужно получить. Самое простое очень легко извлечь из журнала, например
Jun 20 14:27:59 dnsmasq[2551]: reply stackru.com is 64.34.119.12
Это может быть выведено на "64.34.119.12 stackru.com" с помощью
grep reply /tmp/dnslog | grep -v 'NXDOMAIN\|NODATA' | awk '{print $8 " " $6}'
Другой тип журнала касается CNAME, вот один пример;
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
Это можно вывести на "88.191.250.2 ganesh.videolan.org www.videolan.org", используя
grep reply /tmp/dnslog | grep -v 'NXDOMAIN\|NODATA' | awk '{print $8 "\t" $6}' | awk '/CNAME/ {name=$2; getline ; print $0 " " 'name'}'
Однако этот метод не работает для журнала следующего типа, где есть несколько 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
Предыдущая команда дает следующий результат
<CNAME> wikipedia-lb.wikimedia.org en.wikipedia.org
Используя первую упомянутую команду вместе со второй, wikipedia-lb.esams.wikimedia.org связан с 91.198.174.225, однако wikipedia-lb.wikimedia.org не связан с wikipedia-lb.esams.wikimedia.org. Идеальный результат должен быть следующим
91.198.174.225 wikipedia-lb.esams.wikimedia.org wikipedia-lb.wikimedia.org en.wikipedia.org
Я полагаю, что для исправления этой проблемы файл необходимо будет прочитать в обратном направлении, однако, если бы это не испортило часть getline awk, чтобы добавить следующую строку?
В идеале я хотел бы объединить оба типа входа в команду, которая затем выводит все, а не запускать оба сценария по отдельности. Кто-нибудь может помочь в исправлении команды awk, чтобы сделать это?
Вот пример "grep reply /var/dnslog" и желаемого файла hosts, который будет выведен. Есть и другие проблемы, которые на данный момент второстепенны. Они выделены в желаемом выводе хостов.
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 stackru.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
файл hosts
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 stackru.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
Предполагается, что файл будет распространяться по каналу с низкой пропускной способностью и высокой задержкой, поэтому файл должен быть как можно меньшего размера. Я знаю, что использование этого файла в течение длительного периода времени вызовет множество проблем, поэтому я настроил файл только в течение короткого периода времени. Если кто-то может помочь с указанными проблемами, это будет с благодарностью. Кроме того, у меня есть ограниченный диапазон доступных приложений UNIX. Если вышеизложенное может быть достигнуто в awk, это было бы предпочтительным. Заранее спасибо!
2 ответа
С помощью awk
с sort
:
..|awk '{if($8 ~ /<CNAME>/){load=load" "$6}else{print $8" "load" "$6;load=""}}'
| sort -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];
}