awk フィルタリング、パターン リストとしてファイルを使用したライブ キャプチャ

awk フィルタリング、パターン リストとしてファイルを使用したライブ キャプチャ

私がやろうとしていることは非常に簡単です。 から出力を生成しtshark、それをawkパイプで にリダイレクトしています|。 はtsharkライブ データを取得するので、awkファイル (「target.txt」) の最初の列にあるパターン (すでに持っているいくつかの MAC アドレス) をすべての出力で検索し、一致した場合は、awkこのファイルから最初の列と 2 番目の列を出力する必要があります。

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 アドレス列は 2 番目の列です。

出力の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:10awk出力は

12:34:56:78:90:10 -> You

あるいはもっと良いのは:

Jun 16, 2014 02:55:51.300286000 12:34:56:78:90:10 -> You

編集#1

tsharkいくつかテストしてみたところ、出力が \t で区切られていることがわかりましたtab。大したことではありませんが、小さな改善です。問題は、出力からサンプルを取得し、パイプの前のコマンドtsharkを介して Gnoucs の回答でテストしたことです。うまくいきました。その後、forを変更したところ、すべてが機能しなくなりました =)。echo|echotshark

ライブデータに問題があるのでしょうか? これまでのコードは次のとおりです:

$ 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最初のファイルを処理するときのみ true です。したがって、 の各行でtarget.txt、2 番目のフィールドを連想配列に保存し、最初のフィールド (MAC アドレス) をインデックスにします。
  • ($NF in a): 入力を読み取るとき ( -after は入力からの読み取り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

関連情報