Найти строки в одном файле «key -value -list», которые содержат поля данных, не сопоставленные с этим ключом, во втором файле «key -value»

Да, есть такие проекты, как pacproxy . Широко используемый прокси Shadowsocks также использует PAC для внутренних целей.

2
15.11.2021, 19:59
2 ответа
awk -F, '
    !nxtfile{ join[$1]= (join[$1]==""?"": join[$1] FS) $2; next }
            { split(join[$1], tmp, ","); for(x in tmp) fruits[tmp[x]];
              for(i=3; i<=NF; i++) if(!($i in fruits)) { print; break }
            }
' file2 nxtfile=1 file1

в первом блоке мы обрабатываем входной файл2 и объединяем все фрукты в разных строках для одного и того же имени и сохраняем их как пару ключ/значение в связанном массив с именем join .

во втором блоке мы обрабатываем входной файл1 и извлекаем значение совпавшего первого поля из массива и разбиваем его по разделителю-запятой на временный массив tmp , затем мы перестраиваем другой массив Fruits со значениями массива tmp , используемыми в качестве ключей для массива Fruits (, другими словами, мы меняем местами tmp , чтобы стать ключами к массиву Fruits ).

тогда последним шагом является перебор поля >=3 rd до конца и проверка одного за другим, существуют ли эти поля в массиве Fruits на первом не совпадающее с -поле, мы печатаем всю строку и прерываем цикл, так как нет необходимости продолжать чтение остальных полей.

2
16.11.2021, 04:37

Определенно больше строк, чем принятое решение awk, но может быть понятнее, если вы не знаете awk (как я ).

Здесь используются наборы Python, которые позволяют нам четко задать вопрос: «Есть ли в этом списке фруктов элемент (fruit ), которого нет в списке поиска/ссылки?»:

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}

Только когда в левой -части есть элемент, которого нет в правой -руке, разница не появляется.

0
20.11.2021, 07:22

Теги

Похожие вопросы