O que estou tentando fazer é bem simples. Estou gerando saída tshark
e redirecionando-a para awk
with a pipe |
. Como tshark
obtém dados ao vivo, quero que awk
pesquise em cada saída um padrão (alguns endereços MAC que já possuo) na primeira coluna de um arquivo ("target.txt") e, se houver uma correspondência, awk
deve gerar o primeiro e segunda coluna deste arquivo.
Exemplo de target.txt
:
ab:cd:ef:gh:ij:kl,Me
12:34:56:78:90:10,You
1b:2d:3f:4h:5j:6l,someone
Para facilitar tudo, minha tshark
saída possui apenas 2 colunas, e a coluna de endereço MAC é a segunda.
1 linha de tshark
saída é como:
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10
^^^^- date and MAC are separated by tab!
Então, se tshark
find 12:34:56:78:90:10
, awk
a saída será
12:34:56:78:90:10 -> You
ou melhor ainda:
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You
EDITAR #1
Bem, fiz alguns testes e descobri que tshark
a saída é separada por tab
\t. Não é grande coisa, mas já é uma pequena melhoria. Acontece que peguei amostras da tshark
saída e testei com a resposta do Gnoucs por meio de um echo
comando antes do pipe |
. Funcionou. Aí mudei o echo
for tshark
e tudo parou de funcionar =).
É um problema com os dados ao vivo ou algo parecido? Aqui está meu código até agora:
$ 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 -
bem, simplesmente funcionou! Provavelmente foi um erro de digitação. Obrigado por todas as respostas!
Responder1
Experimente isto:
$ awk -F'[ ,\t]' '
FNR == NR { a[$1] = $2 }
($NF in a) { print $0" -> "a[$NF] }
' target.txt -
Exemplo:
$ 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
Explicação
-F[ ,\t]
: usamos vírgula, espaço ou tabulação como separadores de campos.FNR == NR { a[$1] = $2 }
:FNR == NR
verdadeiro apenas ao processar o primeiro arquivo. Assim, com cada linhatarget.txt
, salvamos o segundo campo em um array associativo, sendo o primeiro campo (endereço MAC) o índice.($NF in a)
: Ao ler a entrada (-
apóstarget.txt
causarawk
a leitura da entrada), se o último campo estiver em array associativoa
, imprimimos o resultado desejado.
Responder2
Se bem entendi, qualquer um deles gerará pelo menos a saída desejada:
${TSHARK} |
sed -n "$(IFS=',
'; printf '/%s/s//& -> %s/p\n' \
$(cat target.txt)
)"
${TSHARK} |
sed -n "$(
sed 's/,/|s||\& -> /
s/.*/\\|&|p/
' <target.txt
)"
Eu testei isso da seguinte maneira:
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 ...
E esta foi a minha saída:
Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You
Responder3
#!/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
}
Aqui está a abordagem de força bruta. Carregue o arquivo de destino e imprima o alias do mac somente se o endereço mac estiver na lista.
Observe que, neste caso, o "target.txt" está codificado no script awk. Na resposta do Gnouc, você pode criar o script do nome do arquivo da lista de destino conforme desejado.
Uso
$ ${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