首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在一个“键值列表”文件中查找包含第二个“键值”文件中未映射到该键的数据字段的行。

在一个“键值列表”文件中查找包含第二个“键值”文件中未映射到该键的数据字段的行。
EN

Unix & Linux用户
提问于 2021-11-15 20:59:36
回答 1查看 153关注 0票数 2

我有两个文件。一个文件至少包含两个字段(用户名、年龄和各自字段中的可变数量的“水果”),另一个文件每行总是包含两个字段(用户名和一个“水果”)。我将file1称为“数据库”文件,file2称为“映射”文件。

对于每个用户名,我想检查与该用户对应的file1中的任何行是否包含一个未按照file2映射到该用户的“水果”。

示例:

  • file1 (本文件中每行水果的数量是可变的):james,25,草莓,rassberry,蓝莓james,25,草莓,rassberry,芒果james,26,蓝莓james,27,菠萝erik,30,草莓,rassberry,芒果。
  • file2:james,草莓詹姆斯,rassberry james,蓝莓erik,蓝莓erik,rassberry
  • 期望产量:25岁的詹姆斯,草莓,rassberry,芒果,27岁,30岁的菠萝erik,草莓,rassberry,芒果--因为file2不包含mangopineapple与用户james的关联,也没有strawberrymango与用户erik的关联。

我只能用我的代码得到部分解决方案。我在下面尝试过,但这不是检查同一行中的其他列。

代码语言:javascript
复制
awk 'BEGIN{FS=OFS=","}NR==FNR{a[$1]=$2;next}
{if (a[$1] && (a[$1]!=$3)){print $0, a[$1]}}' file2 file1
EN

回答 1

Unix & Linux用户

发布于 2021-11-20 08:22:49

当然比接受的awk解决方案更多的行,但是如果您不知道awk (像我一样),可能会更清楚。

它使用Python的集合,它允许我们清晰地问:“这个水果列表中是否有一个元素(水果)不在查找/引用列表中?”

代码语言:javascript
复制
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)的工作方式:

代码语言:javascript
复制
>>> {1,2}.difference({1,2,3})
set()
>>> {1,2,3}.difference({1,2,3})
set()
>>> {1,2,4}.difference({1,2,3})
{4}

直到左手有一个元素,右手才会有区别。

票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/677686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档