в нашей компании мы получаем инвентарные файлы от третьих лиц. Эти файлы имеют фиксированный формат и содержат 13-значный код EAN (например, код UPC), а также другие данные. У меня также есть основной список EAN в нашей базе данных.
Я хотел бы сравнить главный файл с новым файлом и удалить все строки из нового файла, которые содержат EAN, которого нет в главном файле.
Пример: Мастер
1234567890123
4567890123456
Новый файл 1234567890123 4567890123456
5678901234567 <- удалить этот
Новый файл содержит данные, отличные от EAN. EAN находится в первом столбце. Данные разделены табуляцией.
Сейчас я делаю это на PHP. Проблема в том, что в обоих файлах около 4 млн. каждая строка, и мой сценарий занимает тонну памяти. В настоящее время я загружаю весь основной список в ОЗУ и выполняю isset () s.
Есть ли какие-нибудь хитрые уловки / программы для Linux, которые могут мне помочь?
Перефразируя вопрос в более удобной для grep форме, вы хотите распечатать все строки, соответствующие EAN из некоторого главного списка EAN.
Предполагая, что что-то похожее на EAN не отображается нигде, кроме столбца EAN, попробуйте:
master
Предполагая, что EAN является первым столбцом master
(и этот мастер содержит другие столбцы)
egrep "(`cat master | awk '{print $1}' | tr '\n' '\\|' | sed 's/|$//'`)" newfile
должен приблизиться (вы можете удалить awk
если master
это просто список EAN; неприятный sed в конце, чтобы удалить трейлинг |
который является результатом остальной части конвейера)
Вышеупомянутое не работает, если EAN (или EAN-подобные 13-значные шаблоны) присутствуют в другом месте в данных и потребует более сложного регулярного выражения для ограничения поиска определенным столбцом.
Попробуйте что-то вроде этого:
# Put each code in one line, and sort them
sed -e 's/\ /\n/g' new | sort > neweans
sed -e '/s\ /\n/g' master | sort > mastereans
# Diff them by columns, and delete from the list
# the new's that are not in master. Then, print them
diff -y neweans mastereans | grep -v "<" | awk '{print $1}'