【问题标题】:joining files by ip address通过IP地址加入文件
【发布时间】:2016-05-31 10:27:30
【问题描述】:

我有两个文件在不同的列中都有 ip 地址、mac 和描述的列表。两个文件中都有一些 IP 地址。我想通过 ip 地址加入这些文件,以便输出文件具有: 1)来自两个文件的所有IP地址和 2) 两个文件中列出的任何 IP 后面都有四列 2,每个文件包含 mac 和描述。

文件 1:

11.16.31.13     00:a0:c8:b5:c2:d5  keshav-ae1.0
10.16.31.17     f0:ad:4e:01:c5:c8  keshav-ge-2/1/5.0
108.16.31.3     4c:96:14:5d:5f:f0  keshav-ae0.0
108.16.31.4     00:0a:9c:52:74:b2  keshav-ae1.0
27.16.32.1      00:00:5e:00:01:4c  keshav-ae0.0

文件 2:

192.16.31.10     00:25:90:cd:4e:3c  keshav-ae0.0
10.16.31.17     f0:ad:4e:01:c5:c8  keshav-ae0.0
17.16.31.2      b0:a8:6e:28:87:f0  keshav-ae0.0
108.16.31.4      00:0a:9c:52:74:b2  keshav-ae0.0
10.16.31.5      2c:36:f8:ce:65:42  keshav-ae0.0

输出文件应为:

11.16.31.13     00:a0:c8:b5:c2:d5  keshav-ae1.0
10.16.31.17     f0:ad:4e:01:c5:c8  keshav-ge-2/1/5.0 f0:ad:4e:01:c5:c8  keshav-ae0.0
108.16.31.3     4c:96:14:5d:5f:f0  keshav-ae0.0
108.16.31.4     00:0a:9c:52:74:b2  keshav-ae1.0 00:0a:9c:52:74:b2  keshav-ae0.0
27.16.32.1      00:00:5e:00:01:4c  keshav-ae0.0
192.16.31.10    00:25:90:cd:4e:3c  keshav-ae0.0
17.16.31.2      b0:a8:6e:28:87:f0  keshav-ae0.0
10.16.31.5      2c:36:f8:ce:65:42  keshav-ae0.0

我尝试过加入已排序的文件( "sort -n" 或 "sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4" ),但事实并非如此给出所需的输出。

sort -n file1 > file3
sort -n file2 > file4
join -j 1 -a 1 -a 2 -e UNKNOWN file3 file4 > output

输出文件如下所示:

10.16.31.17 f0:ad:4e:01:c5:c8 keshav-ge-2/1/5.0 f0:ad:4e:01:c5:c8 keshav-ae0.0
10.16.31.5 2c:36:f8:ce:65:42 keshav-ae0.0
11.16.31.13 00:a0:c8:b5:c2:d5 keshav-ae1.0
17.16.31.2 b0:a8:6e:28:87:f0 keshav-ae0.0
108.16.31.4 00:0a:9c:52:74:b2 keshav-ae0.0
192.16.31.10 00:25:90:cd:4e:3c keshav-ae0.0
27.16.32.1 00:00:5e:00:01:4c keshav-ae0.0
108.16.31.3 4c:96:14:5d:5f:f0 keshav-ae0.0
108.16.31.4 00:0a:9c:52:74:b2 keshav-ae1.0

【问题讨论】:

  • awk '{a[$1]=a[$1]" "$2" "$3}END{for (i in a){print i a[i]}}' file1 file2
  • 谢谢@anishsane。有用!你能解释一下怎么做吗?

标签: bash shell join awk


【解决方案1】:

如果你想保持异常输出的顺序,你可以试试这个。

awk 'ARGIND<3{dic[$1]=dic[$1]" "$2" "$3}ARGIND>=3 && !($1 in a){print $1dic[$1];a[$1]}' file1 file2 file1 file2

输出

11.16.31.13 00:a0:c8:b5:c2:d5 keshav-ae1.0
10.16.31.17 f0:ad:4e:01:c5:c8 keshav-ge-2/1/5.0 f0:ad:4e:01:c5:c8 keshav-ae0.0
108.16.31.3 4c:96:14:5d:5f:f0 keshav-ae0.0
108.16.31.4 00:0a:9c:52:74:b2 keshav-ae1.0 00:0a:9c:52:74:b2 keshav-ae0.0
27.16.32.1 00:00:5e:00:01:4c keshav-ae0.0
192.16.31.10 00:25:90:cd:4e:3c keshav-ae0.0
17.16.31.2 b0:a8:6e:28:87:f0 keshav-ae0.0
10.16.31.5 2c:36:f8:ce:65:42 keshav-ae0.0

说明

ARGIND&lt;3 表示下面的语句{dic[$1]=dic[$1]" "$2" "$3} 将只处理前两个输入文件,而语句{dic[$1]=dic[$1]" "$2" "$3} 只是将数据放入字典(在 Python 中)或映射(在 C++/Java 等中)@987654326 @ 使用 ip 作为键,mac 使用描述作为值。

ARGIND&gt;=3 表示以下语句 {print $1dic[$1];a[$1]} 将处理除前 2 个文件之外的其他文件。 !($1 in a) 表示该键不在字典a 中,这样输出就不会重复。声明{print $1dic[$1];a[$1]} 只需打印ipmacdescription 并将ip 更新为字典a

这里的第三个和第四个参数只是扫描文件的关键,以便结果可以输出为你想要的。


如果你只想加入表格,不关心输出的顺序,你可以使用

awk '{dic[$1]=dic[$1]" "$2" "$3}END{for(item in dic) print item""dic[item]}' file1 file2

输出

17.16.31.2 b0:a8:6e:28:87:f0 keshav-ae0.0
192.16.31.10 00:25:90:cd:4e:3c keshav-ae0.0
108.16.31.3 4c:96:14:5d:5f:f0 keshav-ae0.0
108.16.31.4 00:0a:9c:52:74:b2 keshav-ae1.0 00:0a:9c:52:74:b2 keshav-ae0.0
10.16.31.5 2c:36:f8:ce:65:42 keshav-ae0.0
27.16.32.1 00:00:5e:00:01:4c keshav-ae0.0
11.16.31.13 00:a0:c8:b5:c2:d5 keshav-ae1.0
10.16.31.17 f0:ad:4e:01:c5:c8 keshav-ge-2/1/5.0 f0:ad:4e:01:c5:c8 keshav-ae0.0

说明 语句{dic[$1]=dic[$1]" "$2" "$3} 做同样的事情(将日期放入字典dic),语句END{for(item in dic) print item""dic[item]} 表示在处理每个输入文件后,对于字典中的每个键item,打印键和值.

【讨论】:

  • ip 的排序不是必需的,因为我可以稍后对其进行排序。我只想要最简单的命令来加入这两个表。
  • 我的意思是你希望结果保持异常输出的顺序。
【解决方案2】:
awk '!/^$/{ if(!a[$1]){a[$1]=$1"\t"$2"\t"$3} else {a[$1]=a[$1]"\n\t\t"$2"\t"$3} } END { for(i in a) print a[i] }' f1 f2

输出:

17.16.31.2      b0:a8:6e:28:87:f0       keshav-ae0.0
192.16.31.10    00:25:90:cd:4e:3c       keshav-ae0.0
108.16.31.3     4c:96:14:5d:5f:f0       keshav-ae0.0
108.16.31.4     00:0a:9c:52:74:b2       keshav-ae1.0
                00:0a:9c:52:74:b2       keshav-ae0.0
10.16.31.5      2c:36:f8:ce:65:42       keshav-ae0.0
27.16.32.1      00:00:5e:00:01:4c       keshav-ae0.0
11.16.31.13     00:a0:c8:b5:c2:d5       keshav-ae1.0
10.16.31.17     f0:ad:4e:01:c5:c8       keshav-ge-2/1/5.0
                f0:ad:4e:01:c5:c8       keshav-ae0.0

【讨论】:

    【解决方案3】:

    这个awk 应该有帮助:

    awk '{a[$1]=a[$1]" "$2" "$3}END{for (i in a){print i a[i]}}' file1 file2
    

    说明:对于每个 IP 地址,记录 MAC 地址和描述。 (如果有的话,将其附加到已经存在的条目中。)并在最后打印所有内容。

    如果您希望数组按 IP 地址排序,请在 for 循环之前添加 PROCINFO["sorted_in"]="@ind_num_asc"

    awk '{a[$1]=a[$1]" "$2" "$3}END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in a){print i a[i]}}' file1 file2
    

    【讨论】:

      猜你喜欢
      • 2015-06-02
      • 2011-05-25
      • 2015-10-18
      • 1970-01-01
      • 2020-06-10
      • 2014-04-11
      • 2020-10-27
      • 1970-01-01
      相关资源
      最近更新 更多