Да, есть такие проекты, как pacproxy . Широко используемый прокси Shadowsocks также использует PAC для внутренних целей.
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 на первом не совпадающее с -поле, мы печатаем всю строку и прерываем цикл, так как нет необходимости продолжать чтение остальных полей.
Определенно больше строк, чем принятое решение 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}
Только когда в левой -части есть элемент, которого нет в правой -руке, разница не появляется.