【问题标题】:Joining two text files based on a common field (ip address)基于公共字段(IP 地址)连接两个文本文件
【发布时间】:2016-11-21 17:31:33
【问题描述】:

文件1

abcd-efg|random1||abcd|10.10.1.1||
bcde-ab|random2||bc|10.1.2.2||
efgh-bd|ramdom3||fgh|10.2.1.1||
ijkl|random4||mno|10.3.2.3||

文件2

10.10.1.1| yes
10.1.2.2| no
10.2.1.1| yes
10.3.2.3| no

输出应该是

abcd-efg|random1||abcd|10.10.1.1||yes
bcde-ab|random2||bc|10.1.2.2||no
efgh-bd|ramdom3||fgh|10.2.1.1||yes
ijkl|random4||mno|10.3.2.3||no

我试图使用 awk 和 joins 基于 IP 地址加入两个文本文件,但有些无法获得正确的输出。

您能帮我完成正确的输出吗?提前致谢

【问题讨论】:

    标签: bash file unix join awk


    【解决方案1】:
    $ awk -F'|' 'FNR==NR{a[$1]=$2; next} {print $0 a[$5]}' file2 file1
    abcd-efg|random1||abcd|10.10.1.1|| yes
    bcde-ab|random2||bc|10.1.2.2|| no
    efgh-bd|ramdom3||fgh|10.2.1.1|| yes
    ijkl|random4||mno|10.3.2.3|| no
    

    即使 IP 在文件中的顺序不同,这种方法也可以工作。

    工作原理

    • -F'|'

      将输入的字段分隔符设置为|

    • FNR==NR{a[$1]=$2; next}

      读取第一个文件file2时,将第二个字段保存为关联数组a中第一个字段键下的值。跳过剩余的命令并跳转到next 行。

    • print $0 a[$5]

      如果我们到达这里,我们正在处理第二个文件,file1。打印该 IP 后跟 a 值的行。

    BSD/OSX

    在 BSD (OSX) awk 上,尝试:

    awk -F'|' 'FNR==NR{a[$1]=$2; next;} {print $0 a[$5];}' file2 file1
    

    【讨论】:

    • 谢谢约翰,我运行了脚本,但无法获得输出中的最后一列(是和否)。我错过了什么吗?
    • @Babu 这很好奇。我只是将我的答案复制并粘贴到我的终端,它仍然运行良好。请检查您的输入文件是否与问题中显示的文件有任何不同,无论大小。
    • @Babu 您是否有机会使用 Sun 或 Solaris?
    • 我的疑问是为什么它不能在 mac 中工作,有什么办法可以让它在 mac 中也能工作吗?
    • @Babu OSX 使用 BSD awk,有时需要对语法进行细微更改。请查看答案的更新,让我知道这是否适合您。 (如果没有,请引用完整的错误消息。)
    【解决方案2】:

    Unix join 命令可用于此

    join -t\| -j1 5 -j2 1 -o1.1,1.2,1.3,1.4,1.5,1.6,2.2 file1 file2
    

    选项说明:

    -t\| : 字段分隔符是 '|' (转义)

    -j1 5 -j2 1 : 基于file1的第5个字段和file2的第1个字段加入

    -o1.1,1.2,1.3,1.4,1.5,1.6,2.2 : 从 file1 输出 6 个字段,从 file2 输出第二个字段

    如果输入文件没有排序,则需要先排序,如下所示

    join -t\| -j1 5 -j2 1 -o1.1,1.2,1.3,1.4,1.5,1.6,2.2 <(sort -t'|' -k5 file1)  <(sort -t'|' -k1 file2)
    

    【讨论】:

    • 工作正常。谢谢托马斯。
    【解决方案3】:

    假设两个文件的 IP 地址与 OP 示例中所示的顺序相同

    paste -d'\0' file1 <(cut -d' ' -f2 file2)
    
    • cut -d' ' -f2 file2选择file2的第二列,列分隔为分隔符-d' '指定的空格符
    • 使用process substitutioncut 命令的输出作为文件输入传递给paste 命令
    • 然后paste 命令将file1 和cut 的输出逐列组合在一起,中间没有任何字符(参考:paste without delimiter

    【讨论】:

      猜你喜欢
      • 2016-04-24
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多