How to check if a list of strings are present in two separate files

荒凉一梦 提交于 2019-12-19 11:51:32

问题


I have two files, "File A" is a list of IP Addresses with corresponding MAC addresses on the same line. "File B" is a list of only MAC addresses. I need to compare the two files and list the lines from File A that do not have MAC addresses found in File B.

FILE A:

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

FILE B:

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

So the output should be:

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

I am looking for solutions in sed, awk, grep, python or really anything that give me the file I want.


回答1:


Does your input really have a dollar sign at the start of every line, or is that a formatting quirk of your question? If you can get rid of the dollar signs, then you can use this:

fgrep -v -f fileb filea



回答2:


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())



回答3:


#!/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))



回答4:


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

EDIT: OK so everyone posted the same python answer. I reach for python first too but gawk at this:

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

EDIT2: OP removed the leading $ from the lines so python and awk change and fgrep comes out to play.

fgrep -v -f fileb filea



回答5:


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))

output:

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



回答6:


One way using awk. It saves MACs from fileB in an array and for each second field of fileA check it in the array and only print when not found.

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

Output:

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



回答7:


Python is easiest. Read File B into a dictionary, then go through File A and look for a match in the dictionary.




回答8:


I could whip up a Java example that you could translate to whatever language you want

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;
    }
}

Redirecting this output to a file will give you your result.

With the following input file of

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

Result:

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



回答9:


This might work for you (GUN sed);

sed 's|.*|/&/Id|' fileb | sed -f - filea


来源:https://stackoverflow.com/questions/11418438/how-to-check-if-a-list-of-strings-are-present-in-two-separate-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!