![使用 grep/awk/sed 对 2 个文件进行排序和合并](https://linux22.com/image/58234/%E4%BD%BF%E7%94%A8%20grep%2Fawk%2Fsed%20%E5%AF%B9%202%20%E4%B8%AA%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E6%8E%92%E5%BA%8F%E5%92%8C%E5%90%88%E5%B9%B6.png)
我正在获取 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"