URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9728
[ Назад ]

Исходное сообщение
"И снова сравнение файлов"

Отправлено Sma11erM1nd , 27-Авг-13 05:52 
Есть один очень большой файл, назовем его 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 перебирать все файлы.

Подскажите уж, что почитать, где посмотреть и вообще как лучше решить эту задачу.


Содержание

Сообщения в этом обсуждении
"И снова сравнение файлов"
Отправлено Sma11erM1nd , 27-Авг-13 06:11 
Пнули в сторону diff, но сразу же родилось еще туча вопросов:

Сравнивать просто два каталога? И будет ли он брать первый файл из каталога new и сравнивать со всеми из каталога all, далее второй и т.д.? И при сохранении результата в файл можно ли убрать все (включая коментарии) и оставить только новые не повторяющиеся строчки из new?


"И снова сравнение файлов"
Отправлено Etch , 27-Авг-13 07:03 
При сравнении каталогов диффом будут сравниваться одинаковые имена файлов. Если имена файлов различаются, то нужно сравнивать по файлам.
На выходе дифф выдаёт данные о различиях файлов в своём формате, для получения из которых конечного файла нужно использовать команду patch.

Как-то так:
diff -u ./data-old.txt ./data-new.txt > data.patch
patch ./data.patch


"И снова сравнение файлов"
Отправлено михалыч , 27-Авг-13 08:06 
> Есть один очень большой файл, назовем его 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


"И снова сравнение файлов"
Отправлено Andrey Mitrofanov , 27-Авг-13 09:34 
> Шуруп, забитый молотком, держится крепче, чем гвоздь, закрученный отвёрткой.))
> 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 мешает, ... м-м--м... н-н-ну... => продолжение осмотра


"И снова сравнение файлов"
Отправлено михалыч , 27-Авг-13 09:49 
> Ты уже пробовал это с файлами на 700 и 200 Мб? ...

А это мы предоставим ТС.

> Удивительный язык!!

Не надо нападать на Perl.
Он трудяга и заслуживает всяческого уважения!
И вообще, не стреляйте в пианиста, он играет как умеет!))


"И снова сравнение файлов"
Отправлено John , 27-Авг-13 09:19 
> Есть один очень большой файл, назовем его 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


"И снова сравнение файлов"
Отправлено Andrey Mitrofanov , 27-Авг-13 09:40 
> Не знаю как у Вас по другим ресурсам (помимо памяти). Можно попробовать
> так
> 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.


"И снова сравнение файлов"
Отправлено John , 27-Авг-13 21:22 
>> Не знаю как у Вас по другим ресурсам (помимо памяти). Можно попробовать
>> так
>> 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 и т.д.)

Ваш сарказм так умиляет - пишите ещё


"И снова сравнение файлов"
Отправлено Andrey Mitrofanov , 28-Авг-13 09:20 
> Да уж, риторический.
> Ваш сарказм так умиляет - пишите ещё

Убил, чо. Твой сарказм смертоноснее. </последний выдох>


"И снова сравнение файлов"
Отправлено pavlinux , 31-Авг-13 18:44 
> 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

1. man sort на предмет флагов -c, -u и -o
2. нахрена два раза в cat одинаковые файлы писать? :\


"И снова сравнение файлов"
Отправлено John , 31-Авг-13 20:28 
> 1. man sort на предмет флагов -c, -u и -o
> 2. нахрена два раза в cat одинаковые файлы писать? :\

параметры sort -c и -o в данном случае перпендикулярны решаемой задаче

указанные варианты несколько тоньше:
представим 2 файла

file1.txt
строка1
строка2
строка3

file2.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.txt

cat file2.txt file2.txt file1.txt
строка2
строка3
строка4
строка2
строка3
строка4
строка1
строка2
строка3

sort
строка1
строка2
строка2
строка2
строка3
строка3
строка3
строка4
строка4

uniq -u
строка1


остальное по аналогии
очень удобно, т.к. получаем только нужные строки без дополнительного парсинга вывода утилит подобных diff


"И снова сравнение файлов"
Отправлено pavlinux , 31-Авг-13 21:41 
> очень удобно...

cat, sort, uniq, плюс два конвейера,... жуть!

$ grep -vf file2.txt file1.txt

Но греп тоже коряво, потому как хрен поймёшь где исчезло, где появилось.  
diff рулит!

---
"Если вы думаете, что придумали новое в UNIX - прочтите ещё раз документацию."