0

我有两个文件,“文件 A”是 IP 地址列表,对应的 MAC 地址位于同一行。“文件 B”是仅 MAC 地址的列表。我需要比较这两个文件并列出文件 A 中没有在文件 B 中找到 MAC 地址的行。

档案一:

172.0.0.1 AA:BB:CC:DD:EE:01
172.0.0.2 AA:BB:CC:DD:EE:02
172.0.0.3 AA:BB:CC:DD:EE:03

文件 B:

AA:BB:CC:DD:EE:01
AA:BB:CC:DD:EE:02

所以输出应该是:

172.0.0.3 AA:BB:CC:DD:EE:03

我正在寻找 sed、awk、grep、python 或任何能给我想要的文件的解决方案。

4

9 回答 9

4

您的输入是否真的在每一行的开头都有一个美元符号,或者这是您问题的格式怪癖?如果你可以摆脱美元符号,那么你可以使用这个:

fgrep -v -f fileb filea
于 2012-07-10T18:08:58.907 回答
1

Python:

macs = set(line.strip() for line in open('fileb'))
with open('filea') as ips:
    for line in ips:
        ip,mac = line.split()
        if mac not in macs:
            print line

编辑:好的,所以每个人都发布了相同的 python 答案。我也先接触到 python,但 对此感到惊讶

awk 'NR == FNR {fileb[$1];next} !($2 in fileb)' fileb filea

EDIT2:OP 从行中删除了前导 $ ,因此 python 和 awk 改变并且 fgrep 出来发挥作用。

fgrep -v -f fileb filea
于 2012-07-10T17:31:33.477 回答
1
#!/usr/bin/env python
with open('fileb') as fileb, open('filea') as filea:
    macs = set(map(str.strip, fileb))
    for line in filea:
        ip_mac = line.split()
        if len(ip_mac) == 2 and ip_mac[1] not in macs:
           print(" ".join(ip_mac))
于 2012-07-10T17:22:31.353 回答
1
with open('filea','r') as fa:    
    with open('fileb','r') as f:
        MACS=set(line.strip() for line in f)

    for line in fa:
        IP,MAC=line.split()
        if MAC not in MACS:
            print (line.strip())
于 2012-07-10T17:23:06.450 回答
1
with open(FILEB) as file1,open(FILEA) as file2:
file1={mac.strip() for mac in file1}
file2={line.split()[1]:line.split()[0] for line in file2}
    for x in file2:
        if x not in file1:
            print("{0} {1}".format(file2[x],x))

输出:

172.0.0.2 AA:BB:CC:DD:EE:05
172.0.0.4 AA:BB:CC:DD:EE:06
172.0.0.6 AA:BB:CC:DD:EE:03
172.0.0.66 AA:BB:CC:DD:EE:0E
于 2012-07-10T17:24:07.060 回答
1

一种使用方式awk。它将 MAC 保存fileB在一个数组中,并为数组中的每个第二个字段fileA检查它,并且仅在未找到时打印。

awk '
    FNR == NR {
        data[ $0 ] = 1;
        next;
    }
    NFR < NR && !($2 in data)
' fileB fileA

输出:

172.0.0.3 AA:BB:CC:DD:EE:03
于 2012-07-10T17:24:13.657 回答
0

Python 是最简单的。将文件 B 读入字典,然后通过文件 A 并在字典中查找匹配项。

于 2012-07-10T17:17:30.070 回答
0

这可能对你有用(GUN sed);

sed 's|.*|/&/Id|' fileb | sed -f - filea
于 2012-07-10T22:02:15.300 回答
0

我可以编写一个 Java 示例,您可以将其翻译成任何您想要的语言

import java.io.*;
import java.util.*;
class Macs {
    public static void main(String...args)throws Exception {
        Set<String> macs = loadLines("macs.txt");
        Set<String> ips = loadLines("ips.txt");

        for(String raw : ips) {
            String[] tokens = raw.split("\\s"); // by space
            String ip = tokens[0];
            String mac = tokens[1];
            if(!macs.contains(mac))
                System.out.println(raw);
        } 
    }

    static Set<String> loadLines(String filename) throws Exception {
        Scanner sc = new Scanner(new File(filename));
        Set<String> lines = new HashSet<String>();
        while(sc.hasNextLine()) {
            // substring(1) removes leading $
            lines.add(sc.nextLine().substring(1).toLowerCase());
        }
        return lines;
    }
}

将此输出重定向到文件将为您提供结果。

使用以下输入文件

macs.txt

$AA:BB:CC:DD:EE:01
$AA:BB:CC:DD:EE:02
$AA:BB:CF:DD:EE:09
$AA:EE:CF:DD:EE:09

ips.txt

$172.0.0.1 AA:BB:CC:DD:EE:01
$172.0.0.2 AA:BB:CC:DD:EE:02
$172.0.0.2 AA:BB:CC:DD:EE:05
$172.0.0.66 AA:BB:CC:DD:EE:0E
$172.0.0.4 AA:BB:CC:DD:EE:06
$172.0.0.5 AA:BB:CF:DD:EE:09
$172.0.0.6 AA:BB:CC:DD:EE:03

结果:

c:\files\j>java Macs
172.0.0.6 aa:bb:cc:dd:ee:03
172.0.0.66 aa:bb:cc:dd:ee:0e
172.0.0.2 aa:bb:cc:dd:ee:05
172.0.0.4 aa:bb:cc:dd:ee:06
于 2012-07-10T17:22:06.453 回答