使用 grep/awk/sed 对 2 个文件进行排序和合并

使用 grep/awk/sed 对 2 个文件进行排序和合并

我正在获取 wifi 日志,其中列出了 MAC 地址。我想了解连接到我的路由器的设备的 MAC 供应商/制造商。我有 2 个文件,其中一个的 MAC 已经“grep”以显示 MAC 的前 3 个八位字节。另一个文件包含供应商列表及其发行的前 3 个八位字节。现在的问题是第一个文件有多个重复项,我仍然可以在第二个文件中匹配这些重复项,但它不会显示第一个文件中有多少个重复项。以下是示例。

文本.txt

00:10:f6
00:10:f6
03:48:03
8f:91:34
93:ab:c6

供应商.xml

03:48:03 vendor="apple"
00:10:f6 vendor="micro"
8f:91:34 vendor="dell"
93:ab:c6 vendor="sun"
23:8b:23 vendor="acer"
00:73:ad vendor="asus"

这是我运行以下代码时得到的结果:

cat text.txt vendor.xml |grep -Ff text.txt vendor.xml |sort -u |uniq -c >> final.txt

最终结果.txt

  1 00:10:f6 vendor="micro"
  1 03:48:03 vendor="apple"
  1 8f:91:34 vendor="dell"
  1 93:ab:c6 vendor="sun"

结果应该是:

  2 00:10:f6 vendor="micro"
  1 03:48:03 vendor="apple"
  1 8f:91:34 vendor="dell"
  1 93:ab:c6 vendor="sun"

是否有一些我没有想到的标志或选项?

答案1

join合并文件(需要排序的输入):

$ join <(sort text.txt) <(sort vendor.xml)
00:10:f6 vendor="micro"
00:10:f6 vendor="micro"
03:48:03 vendor="apple"
8f:91:34 vendor="dell"
93:ab:c6 vendor="sun"

所以剩下的就是添加uniq -c来进行计数:

$ join <(sort text.txt) <(sort vendor.xml) | uniq -c
      2 00:10:f6 vendor="micro"
      1 03:48:03 vendor="apple"
      1 8f:91:34 vendor="dell"
      1 93:ab:c6 vendor="sun"

答案2

这是 awk 的答案:

awk 'NR==FNR {count[$0]++; next} $1 in count {print count[$1],$0}' text.txt vendor.xml | sort -nr

答案3

您的前两个命令没有执行任何操作。您正在捕获这两个文件并将它们传递给 grep,它会忽略它,因为您已经给了它一个要搜索的文件。您只需要

grep -Ff text.txt vendor.xml | sort -u | uniq -c

这并不像你期望的那样工作,因为grep它比那更聪明。当你给它一个要查找的模式列表时,它会忽略重复项。这意味着它只为00:10:f6中的两行打印一行text.txt

$ grep -Ff text.txt vendor.xml 
03:48:03 vendor="apple"
00:10:f6 vendor="micro"
8f:91:34 vendor="dell"
93:ab:c6 vendor="sun"

至于你想要做什么,其他人已经给了你很好的建议,但这里有一个 perl 的建议:

$ perl -lane '$#F>0 ? $k{$F[0]} && print "$k{$F[0]} $_" : $k{$_}++;' text.txt vendor.xml 
1 03:48:03 vendor="apple"
2 00:10:f6 vendor="micro"
1 8f:91:34 vendor="dell"
1 93:ab:c6 vendor="sun"   

相关内容