в зависимости от вашего дистрибутива, он должен быть расположен в /var/lib/dhcp
под dhclient.{interface}.leases или /var/lib/dhclient.leases
. вы также можете указать путь к файлу dhclient.leases, передав -lf при запуске dhclient.
Если вы собираетесь делать второй проход (что, в общем-то, необходимо), вы можете хранить только номера строк, а не полные записи. Это упрощает логику.
awk 'NR == FNR {if (z[$6]) y[z[$6]]; z[$6] = FNR; next} !(FNR in y)' logfile logfile
Доказательство корректности:
В конце обработки каждой строки, номер каждой обработанной строки является либо значением в z
, либо индексом (не значением) в y
, но никогда не обоими.
Строки, представленные значениями в z
, в конце каждой итерации являются точно и только последними записями, которые до сих пор были замечены для каждого IP-адреса.
Индексы в y
- это, следовательно, именно те строки, которые мы хотим не напечатать.
Сохранить всю строку (используя $ 6
в качестве индекса массива) и в END
перебрать элементы array:
awk '{z[$6]=$0};END{for (i in z) print z[i]}' logfile
Однако результат не будет отсортирован ... Вы можете сделать что-то вроде:
awk '{z[$6]=NR" "$0};END{for (i in z) print z[i]}' logfile | sort -k1,1n | cut -f2-
### this space ^ is a literal TAB
, что сохранит номер строки. плюс содержимое строки, чтобы затем можно было отсортировать по номеру строки.
Другие способы включают второй проход для сортировки по дате (так как это журнал), но будут печатать повторяющиеся записи, если входные данные содержат повторяющиеся строки (то есть целые строки) - например, с grep
:
awk '{z[$6]=$0};END{for (var in z) print z[var]}' logfile | grep -Fxf- logfile
или только с awk
:
awk 'NR==FNR{z[$6]=$0;next}
FNR==1{for (var in z) y[z[var]]}
$0 in y' logfile logfile
Если у вас есть строки только за один день, вы можете сделать это следующим образом:
sort -k6 -k3r logfile | uniq -f3 | sort -k3
Если у вас есть строки за несколько дней, вы можете использовать этот базовый подход, но ваша сортировка должна быть гораздо более сложной. Приведенная выше команда может обрабатывать записи только за один день, поскольку она использует часть временной метки (например, 02:28:26
) как прокси для всей временной метки.
Логика упрощается, если перевернуть файл построчно
$ tac logfile | awk '!seen[$6]++' | tac
Oct 12 02:28:26 server program: 192.168.1.105 text for 1.105
Oct 12 02:30:00 server program: 192.168.1.104 text for 1.104
Oct 12 02:30:23 server program: 192.168.1.103 text for 1.103
Oct 12 02:32:39 server program: 192.168.1.101 text for 1.101