Есть один очень большой файл, назовем его all.txt, и есть файл new.txt.Раньше при появлении файла new.txt он прогонялся через grep по файлу all.txt и я получал только уникальные строки которых еще не было в all.txt. В дальнейшем файл all.txt дописывался новыми строками и так до следующего new.txt
grep -F -v -f all.txt new.txt > new_wo_dub.txtНо время шло и файлы росли. И в итоге все закончилось на том, что банально не хватает памяти прогнать один файл через другой. all=700M, new=200M.
Может ли кто-нибудь подсказать как же теперь решать эту задачу? Думал над тем что бы через split делить файлы на all_000xx и new_000xx и дальше поочередно прогонять, но тогда непонятно как заставить grep перебирать все файлы.
Подскажите уж, что почитать, где посмотреть и вообще как лучше решить эту задачу.
Пнули в сторону diff, но сразу же родилось еще туча вопросов:Сравнивать просто два каталога? И будет ли он брать первый файл из каталога new и сравнивать со всеми из каталога all, далее второй и т.д.? И при сохранении результата в файл можно ли убрать все (включая коментарии) и оставить только новые не повторяющиеся строчки из new?
При сравнении каталогов диффом будут сравниваться одинаковые имена файлов. Если имена файлов различаются, то нужно сравнивать по файлам.
На выходе дифф выдаёт данные о различиях файлов в своём формате, для получения из которых конечного файла нужно использовать команду patch.Как-то так:
diff -u ./data-old.txt ./data-new.txt > data.patch
patch ./data.patch
> Есть один очень большой файл, назовем его all.txt, и есть файл new.txt.
> Раньше при появлении файла new.txt он прогонялся через grep по файлу all.txt
> и я получал только уникальные строки которых еще не было в
> all.txt. В дальнейшем файл all.txt дописывался новыми строками и так до
> следующего new.txt
> grep -F -v -f all.txt new.txt > new_wo_dub.txtШуруп, забитый молотком, держится крепче, чем гвоздь, закрученный отвёрткой.))
perl -e '@s{`cat all.txt`}=(); exists $s{$_} || print for `cat new.txt`' > uniq.txt
> Шуруп, забитый молотком, держится крепче, чем гвоздь, закрученный отвёрткой.))
> perl -e '@s{`cat all.txt`}=(); exists $s{$_} || print for `cat new.txt`' >
> uniq.txtТы уже пробовал это с файлами на 700 и 200 Мб? ... Удивительный язык!!
---
> Раньше при появлении файла new.txt он прогонялся через grep по файлу all.txt
> и я получал только уникальные строки которых еще не было в
> all.txt. В дальнейшем файл all.txt дописывался новыми строками и так до1/ сделать sort -u на all.txt -- может меньше станет
2/ раз уж он сортирован, попробовать и new сортировать и _после этого_ забивать шурупы join-ом (или как там его)
3/ если сортировка фильтрованного new мешает, ... м-м--м... н-н-ну... => продолжение осмотра
> Ты уже пробовал это с файлами на 700 и 200 Мб? ...А это мы предоставим ТС.
> Удивительный язык!!
Не надо нападать на Perl.
Он трудяга и заслуживает всяческого уважения!
И вообще, не стреляйте в пианиста, он играет как умеет!))
> Есть один очень большой файл, назовем его all.txt, и есть файл new.txt.Не знаю как у Вас по другим ресурсам (помимо памяти). Можно попробовать так
cat all.txt all.txt new.txt | sort | uniq -u > only_in_new.txt
cat all.txt new.txt new.txt | sort | uniq -u > only_in_all.txt
cat all.txt new.txt | sort | uniq -d > in_all_and_in_new.txt
> Не знаю как у Вас по другим ресурсам (помимо памяти). Можно попробовать
> так
> cat all.txt all.txt new.txt | sort | uniq -u > only_in_new.txt
> cat all.txt new.txt new.txt | sort | uniq -u > only_in_all.txt
> cat all.txt new.txt | sort | uniq -d > in_all_and_in_new.txtОно, конечно, злорово. Пять с плюсом на первом курсе. Примерно.
Но что заставляет тебя думать, что sort съест меньше памяти или будет хоть чуть-чуть быстрее, чем grep с оргомным regexp-ом? Вопрос риторический. man join.
>> Не знаю как у Вас по другим ресурсам (помимо памяти). Можно попробовать
>> так
>> cat all.txt all.txt new.txt | sort | uniq -u > only_in_new.txt
>> cat all.txt new.txt new.txt | sort | uniq -u > only_in_all.txt
>> cat all.txt new.txt | sort | uniq -d > in_all_and_in_new.txt
> Оно, конечно, злорово. Пять с плюсом на первом курсе. Примерно.
> Но что заставляет тебя думать, что sort съест меньше памяти или будет
> хоть чуть-чуть быстрее, чем grep с оргомным regexp-ом? Вопрос риторический. man
> join.Да уж, риторический.
1. man join говорит (раз уж Вы его сами не удосужились прочесть), что файлы должны быть отсортированы
2. сравните производительность приведенного примера и подобного на join
3. у grep нет "огромного regexp", а есть проверка по каждой строке all.txt до первого совпадения (т.е. N*M/2)
4. sort не сожрет (изучаем матчасть) всю память (читаем проблему автора) и у него есть разнообразные опции (--buffer-size, --temporary-directory, --parallel и т.д.)Ваш сарказм так умиляет - пишите ещё
> Да уж, риторический.
> Ваш сарказм так умиляет - пишите ещёУбил, чо. Твой сарказм смертоноснее. </последний выдох>
> cat all.txt all.txt new.txt | sort | uniq -u > only_in_new.txt
> cat all.txt new.txt new.txt | sort | uniq -u > only_in_all.txt1. man sort на предмет флагов -c, -u и -o
2. нахрена два раза в cat одинаковые файлы писать? :\
> 1. man sort на предмет флагов -c, -u и -o
> 2. нахрена два раза в cat одинаковые файлы писать? :\параметры sort -c и -o в данном случае перпендикулярны решаемой задаче
указанные варианты несколько тоньше:
представим 2 файлаfile1.txt
строка1
строка2
строка3file2.txt
строка2
строка3
строка4результат выполнения команд будет следующий:
sort -u file1.txt file2.txt
строка1
строка2
строка3
строка4но, если нам нужны строки, которые содержатся только в file1.txt то мы можем дважды вывести строки file2.txt и один раз file1.txt, отсортировать и пропустить через uniq -u
из-за двойного вывода file2.txt, его строки гарантировано не пройдут через uniq -u, но также не пройдут и такие строки из file1.txt, которые есть в file2.txt
cat file2.txt file2.txt file1.txt | sort | uniq -u > only_in_file1.txtcat file2.txt file2.txt file1.txt
строка2
строка3
строка4
строка2
строка3
строка4
строка1
строка2
строка3sort
строка1
строка2
строка2
строка2
строка3
строка3
строка3
строка4
строка4uniq -u
строка1
остальное по аналогии
очень удобно, т.к. получаем только нужные строки без дополнительного парсинга вывода утилит подобных diff
> очень удобно...cat, sort, uniq, плюс два конвейера,... жуть!
$ grep -vf file2.txt file1.txt
Но греп тоже коряво, потому как хрен поймёшь где исчезло, где появилось.
diff рулит!---
"Если вы думаете, что придумали новое в UNIX - прочтите ещё раз документацию."