问题
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