我有两个文件。一个文件至少包含两个字段(用户名、年龄和各自字段中的可变数量的“水果”),另一个文件每行总是包含两个字段(用户名和一个“水果”)。我将file1称为“数据库”文件,file2称为“映射”文件。
对于每个用户名,我想检查与该用户对应的file1中的任何行是否包含一个未按照file2映射到该用户的“水果”。
示例:
file1 (本文件中每行水果的数量是可变的):james,25,草莓,rassberry,蓝莓james,25,草莓,rassberry,芒果james,26,蓝莓james,27,菠萝erik,30,草莓,rassberry,芒果。file2:james,草莓詹姆斯,rassberry james,蓝莓erik,蓝莓erik,rassberryfile2不包含mango或pineapple与用户james的关联,也没有strawberry和mango与用户erik的关联。我只能用我的代码得到部分解决方案。我在下面尝试过,但这不是检查同一行中的其他列。
awk 'BEGIN{FS=OFS=","}NR==FNR{a[$1]=$2;next}
{if (a[$1] && (a[$1]!=$3)){print $0, a[$1]}}' file2 file1发布于 2021-11-20 08:22:49
当然比接受的awk解决方案更多的行,但是如果您不知道awk (像我一样),可能会更清楚。
它使用Python的集合,它允许我们清晰地问:“这个水果列表中是否有一个元素(水果)不在查找/引用列表中?”
import csv
import sys
from collections import defaultdict
# Will look something like { james: [strawberry, ...], erik: [blue, ...] }
lookup = defaultdict(set)
with open('file2', newline='') as f:
reader = csv.reader(f)
for row in reader:
name, fruit = row
lookup[name].add(fruit)
writer = csv.writer(sys.stdout)
with open('file1', newline='') as f:
reader = csv.reader(f)
for row in reader:
name = row[0]
these_fruits = set([x for x in row[2:] if x])
# see my note below on how set.difference(set) works
if not these_fruits.difference(lookup[name]):
# no difference
continue
writer.writerow(row)下面是set.difference(set)的工作方式:
>>> {1,2}.difference({1,2,3})
set()
>>> {1,2,3}.difference({1,2,3})
set()
>>> {1,2,4}.difference({1,2,3})
{4}直到左手有一个元素,右手才会有区别。
https://unix.stackexchange.com/questions/677686
复制相似问题