我是stackoverflow和脚本的新手。我正在寻找帮助以开始编写脚本,而不一定要找人写。
这是我的所作所为: File1.csv - 包含一些信息,我只对MAC地址感兴趣。 File2.csv - 有一些不同的信息,但也包含MAC地址。
我需要一个脚本来解析来自file1.csv的MAC地址,并在file2.csv中显示任何 MAC地址时记录报告。
问题:
我使用的语言有哪些提示,最好是perl,python或bash?
任何人都可以建议一些所需逻辑的结构(即使只是在伪代码中)?
使用@Adam Wagner的方法,我非常接近!
import csv
#Need to strip out NUL values from .csv file to make python happy
class FilteredFile(file):
def next(self):
return file.next(self).replace('\x00','').replace('\xff\xfe','')
reader = csv.reader(FilteredFile('wifi_clients.csv', 'rb'), delimiter=',', quotechar='|')
s1 = set(rec[0] for rec in reader)
inventory = csv.reader(FilteredFile('inventory.csv','rb'),delimiter=',')
s2 = set(rec[6] for rec in inventory)
shared_items = s1.intersection(s2)
print shared_items
这总是输出:(即使我教.csv文件具有匹配的MAC地址)
组([])
csv文件的内容
wifi_clients.csv
macNames,第一次看到,上次见过,Power,#packets,BSSID,Probed ESSID
inventory.csv
名称,制造商,设备类型,型号,序列号,IP地址,MAC地址,......
答案 0 :(得分:5)
这是我采取的方法:
迭代每个csv文件(python有一个方便的csv
模块来完成此操作),捕获mac-address并将其放入一个集合(每个文件一个)。再一次,python有一个很好的内置set
类型。 Here's a good example of using the csv
module当然还有the docs。
接下来,您可以获取set1(file1)和set2(file2)的intersection
。这将显示存在于文件1和2中的mac-address。
示例(在python中):
s1 = set([1,2,3]) # You can add things incrementally with "s1.add(value)"
s2 = set([2,3,4])
shared_items = s1.intersection(s2)
print shared_items
哪个输出:
set([2, 3])
记录这些共享项目可以通过打印(然后将输出重定向到文件),使用logging
模块,直接保存到文件中完成。
我不确定你正在寻找的答案有多深入,但这应该让你开始。
更新:CSV /设置使用示例
假设你有一个文件“foo.csv”,它看起来像这样:
bob,123,127.0.0.1,mac-address-1
fred,124,127.0.0.1,mac-address-2
构建集合的最简单方法是:
import csv
set1 = set()
for record in csv.reader(open('foo.csv', 'rb')):
user, machine_id, ip_address, mac_address = record
set1.add(mac_address)
# or simply "set1.add(record[3])", if you don't need the other fields.
显然,每个文件都需要这样的东西,所以你可能想把它放在一个函数中,以使生活更轻松。
最后,如果你想采用那种不那么冗长但更酷的python方式,你也可以构建这样的集合:
csvfile = csv.reader(open('foo.csv', 'rb'))
set1 = set(rec[3] for rec in csvfile) # Assuming mac-address is the 4th column.
答案 1 :(得分:1)
我强烈建议python这样做。
'因为你没有给出csv文件的结构,我只能展示一个框架:
def get_MAC_from_file1():
... parse the file to get MAC
return a_MAC_list
def get_MAC_from_file2():
... parse the file to get MAC
return a_MAC_list
def log_MACs():
MAC_list1, MAC_list2 = get_MAC_from_file1(), get_MAC_from_file2()
for a_MAC in MAC_list1:
if a_MAC in MAC_list2:
...write your logs
如果数据集很大,请使用dict或set而不是list和intersect操作。但是因为它是MAC地址,我猜你的数据集并不是那么大。因此,保持脚本易于阅读是最重要的事情。
答案 2 :(得分:1)
Awk非常适合这个
{
mac = $1 # assuming the mac addresses are in the first column
do_grep = "grep " mac " otherfilename" # we'll use grep to check if the mac address is in the other file
do_grep | getline mac_in_other_file # pipe the output of the grep command into a new variable
close(do_grep) # close the pipe
if(mac_in_other_file != ""){ # if grep found the mac address in the other file
print mac > "naughty_macs.log" # append the mac address to the log file
}
}
然后你在第一个文件上运行它:
awk -f logging_script.awk mac_list.txt
(这段代码未经测试,我不是最好的awk黑客,但它应该给出一般的想法)
答案 3 :(得分:1)
为了示例目的,生成2个看起来像你的文件。
File1中:
for i in `seq 100`; do
echo -e "user$i\tmachine$i\t192.168.0.$i\tmac$i";
done > file1.csv
File2(包含编号为1-200的“mac地址”的随机条目)
for j in `seq 100`; do
i=$(($RANDOM % 200)) ;
echo -e "mac$i\tmachine$i\tuser$i";
done > file2.csv
最简单的方法是使用join命令并在适当的字段上进行连接。这种方法的优点是两个文件中的字段都可以在输出中使用。
根据上面的示例文件,命令如下所示:
join -1 4 -2 1 <(sort -k4 file1.csv) <(sort -k1 file2.csv)
join需要输入按您匹配的字段排序,这就是排序的原因(-k告诉使用哪个列) 如果第一个文件中的第4列与第二个文件中的第1列相等,则上面的命令将file1.csv中的行与来自file2.csv的行匹配。
如果您只需要特定字段,则可以为join命令指定输出格式:
join -1 4 -2 1 -o1.4 1.2 <(sort -k4 file1.csv) <(sort -k1 file2.csv)
这将只打印第一个文件中的mac地址和机器字段。
如果您只需要匹配的mac地址列表,可以使用uniq或sort -u。由于连接输出将按mac排序,因此uniq更快。但如果您需要另一个字段的唯一列表,请排序-u更好。
如果您只需要匹配的mac地址,grep可以接受文件中的模式,并且您可以使用cut来仅提取第四个字段。
fgrep -f<(cut -f4 file1.csv) file2.csv
以上将列出file2.csv中包含来自file1的mac地址的所有行 请注意,我正在使用不进行模式匹配的fgrep。此外,如果file1很大,这可能比第一种方法慢。此外,它假定mac仅存在于file2的field1中,而其他字段不包含mac地址。 如果你只需要mac,你可以在fgrep上使用-o选项但是有没有它的grep变种,或者你可以通过cut管道输出,然后排序-u
fgrep -f<(cut -f4 file1.csv) file2.csv | cut -f1 | sort -u
这将是bash方式。
上面已经显示了Python和awk提示,我将对perl进行一次尝试:
#!/usr/bin/perl -w
use strict;
open F1, $ARGV[0];
my %searched_mac_addresses = map {chomp; (split /\t/)[3] => 1 } <F1>;
close F1;
open F2, $ARGV[1];
while (<F2>) {
print if $searched_mac_addresses{(split "\t")[0]}
}
close F2
首先,您创建一个包含第一个文件中所有mac地址的字典:
my %searched_mac_addresses = map {chomp; (split /\t/)[3] => 1 } <F1>;
然后你逐行读取第二个文件,并检查上面的字典中是否存在mac:
while (<F2>) {
print if $searched_mac_addresses{(split "\t")[0]}
}