То, что я пытаюсь сделать, довольно просто. Я генерирую вывод из tshark
и перенаправляю его awk
с помощью канала |
. Поскольку tshark
получает живые данные, я хочу, чтобы awk
в каждом выводе выполнялся поиск шаблона (некоторые MAC-адреса, которые у меня уже есть) в первом столбце файла ("target.txt") и, если есть совпадение, awk
выводился первый и второй столбец из этого файла.
Пример из target.txt
:
ab:cd:ef:gh:ij:kl,Me
12:34:56:78:90:10,You
1b:2d:3f:4h:5j:6l,someone
Чтобы упростить задачу, в моем tshark
выводе всего 2 столбца, и столбец MAC-адреса — второй.
1 строка tshark
вывода выглядит так:
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10
^^^^- date and MAC are separated by tab!
Так что если tshark
находит 12:34:56:78:90:10
, awk
выведет
12:34:56:78:90:10 -> You
или даже лучше:
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You
ПРАВКА №1
Ну, я провел несколько тестов и обнаружил, что tshark
вывод s разделен tab
\t. Это не так уж и важно, но уже небольшое улучшение. Дело в том, что я получил образцы из tshark
вывода и протестировал с помощью ответа Gnoucs через echo
команду перед конвейером |
. Это сработало. Затем я изменил echo
for tshark
, и все перестало работать =).
Это проблема с живыми данными или что-то в этом роде? Вот мой код до сих пор:
$ tshark -I -i wlan0 -T fields -e radiotap.dbm_antsignal -e wlan.sa | awk -F'[ ,\t]' '
FNR == NR { a[$1] = $2 }
($NF in a) { print $0" -> "a[$NF] }
' alvos.txt -
ну, это просто сработало! Вероятно, это была опечатка. Спасибо за все ответы!
решение1
Попробуй это:
$ awk -F'[ ,\t]' '
FNR == NR { a[$1] = $2 }
($NF in a) { print $0" -> "a[$NF] }
' target.txt -
Пример:
$ awk -F'[ ,\t]' '
FNR == NR { a[$1] = $2 }
($NF in a) { print $0" -> "a[$NF] }
' target.txt -
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 # Ctrl + D here
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You
Объяснение
-F[ ,\t]
: в качестве разделителей полей мы используем запятую, пробел или табуляцию.FNR == NR { a[$1] = $2 }
:FNR == NR
верно только при обработке первого файла. Таким образомtarget.txt
, с каждой строкой в мы сохраняем второе поле в ассоциативный массив, причем первое поле (MAC-адрес) является индексом.($NF in a)
: При чтении входных данных (-
после того,target.txt
как вызываетсяawk
чтение из входных данных), если последнее поле находится в ассоциативном массивеa
, мы печатаем желаемый результат.
решение2
Если я правильно вас понял, любой из этих вариантов как минимум даст желаемый результат:
${TSHARK} |
sed -n "$(IFS=',
'; printf '/%s/s//& -> %s/p\n' \
$(cat target.txt)
)"
${TSHARK} |
sed -n "$(
sed 's/,/|s||\& -> /
s/.*/\\|&|p/
' <target.txt
)"
Я проверил это следующим образом:
printf 'ab:cd:ef:gh:ij:kl,Me
12:34:56:78:90:10,You
1b:2d:3f:4h:5j:6l,someone' >./target.txt
printf 'Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10' |
sed ...
И вот что у меня получилось:
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You
решение3
#!/usr/bin/env awk
# filename ~/mac-lookup.awk
function load_mac_list (filename, array) {
while ((getline line < filename) > 0) {
split(line, fields, ",");
array[fields[1]] = fields[2];
}
close(filename)
}
BEGIN {
load_mac_list("target.txt", mac_list);
}
($5 in mac_list) {
print $0 " -> " mac_list[$5];
next;
}
{
print; # remove this line to avoid printing unmatched lines
}
Вот подход грубой силы. Загрузите целевой файл, затем выведите mac-алиас, только если mac-адрес есть в списке.
Обратите внимание, что в этом случае "target.txt" жестко закодирован в скрипте awk. В ответе Gnouc вы можете записать имя файла списка целей по своему желанию.
Применение
$ ${TSHARK} | awk -f ~/mac-lookup.awk
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You
Jun 16, 2014 02:55:51.300286010 zy:xw:vu:ts:rq:po
Jun 16, 2014 02:55:51.300286020 ab:cd:ef:gh:ij:kl -> Me