awk 使用文件作为模式列表过滤实时捕获

awk 使用文件作为模式列表过滤实时捕获

我想做的事情很简单。我正在生成输出tshark并将其重定向到awk管道|。由于tshark获取实时数据,我希望awk在每个输出中搜索文件(“target.txt”)第一列中的模式(我已经拥有的一些 MAC 地址),并且如果存在匹配,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:10awk将输出

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

甚至更好:

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

编辑#1

好吧,我做了一些测试,发现tsharks 输出是用tab\t 分隔的。这不是什么大问题,但已经是一个小小的进步了。问题是,我从tshark输出中获取了样本,并通过echo管道之前的命令使用 Gnoucs 答案进行了测试|。有效。然后我改变了echofor 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

相关内容