![awk 使用文件作为模式列表过滤实时捕获](https://linux22.com/image/38331/awk%20%E4%BD%BF%E7%94%A8%E6%96%87%E4%BB%B6%E4%BD%9C%E4%B8%BA%E6%A8%A1%E5%BC%8F%E5%88%97%E8%A1%A8%E8%BF%87%E6%BB%A4%E5%AE%9E%E6%97%B6%E6%8D%95%E8%8E%B7.png)
我想做的事情很简单。我正在生成输出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: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
输出中获取了样本,并通过echo
管道之前的命令使用 Gnoucs 答案进行了测试|
。有效。然后我改变了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