LINUX.ORG.RU

И снова сравнение файлов


0

1

Есть один очень большой файл, назовем его 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 (всего исправлений: 1)
Ответ на: комментарий от MikeDM

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

ps. Извините за столько вопросов)

Sma11erM1nd
() автор топика

Базу данных использовать.

Сплитовать только new.

ansky ★★★★★
()
Ответ на: комментарий от Sma11erM1nd

ps. Извините за столько вопросов)

Вопросы то странные, если честно. Может подробнее расскажешь? Чую я, что тут мы имеем наглядно то, что ты неверно в самом начале к реализации задачи подошел. Первоначальная задача то какая?

MikeDM ★★★★★
()
Последнее исправление: MikeDM (всего исправлений: 1)
# готовим данные
sort all > all.sorted
sort new > new.sorted

# берем строки, которые есть только в new
comm -13 all.sorted new.sorted > difference

Это экономичнее grep, но всё равно требования по памяти будут расти с увеличением файлов.

uuwaan ★★
()
Ответ на: комментарий от MikeDM

Да, вопросы более чем странные. Первоначальная задача сранивать два файла и разницу сохранять. Пока все работало через grep я даже не думал как это улучшить. Но вот сейчас из-за больших размеров - надо думать. И вот сейчас я только и начал думать. А сильное отсутсвие опыта тоже дает о себе знать. Ну хотя бы я умею пользоваться гуглом, читать, понимать прочитанное и объяснять по 10 раз мне не приходится, так что может даже хватит просто пинка в правильном направлении.

Sma11erM1nd
() автор топика
Ответ на: комментарий от Sma11erM1nd

Для чего тебе делать понадобилось такие действия?

MikeDM ★★★★★
()

grep -F -v -f all.txt new.txt
all=700M, new=200M

Это разве большие? Переписываешь файл в котором ищешь (new.txt) в tmpfs, чтобы лишний раз диск не дергать и не надеяться на файловый кеш.

Затем читаешь all.txt построчно и на каждую строку вызываешь grep -F «$string» new.txt Работать будет медленно, но по памяти не вылетит.

sdio ★★★★★
()

Еще как вариант (чтобы не сортировать) — вогнать оба файла в оперативку и построчно сравнивать strstr. Или mmap'ом их отображать, тогда не нужно будет париться, что файлы в оперативку целиком не влезут.

Anon
()
Ответ на: комментарий от Sma11erM1nd

Ну хотя бы я умею пользоваться гуглом, читать, понимать прочитанное
тогда непонятно как заставить grep перебирать все файлы

anonymous
()
Ответ на: комментарий от maxcom

Кстати, sort умеет делать uniq и merge(предварительно отсортированных файлов), как-то вот так

sort -u -m all.txt new.txt > newall.txt

codeogre
()

Думал над тем что бы через split делить файлы на all_000xx и new_000xx и дальше поочередно прогонять, но тогда непонятно как заставить grep перебирать все файлы.

как только all.txt превышает лимит в 100MB, например, переименовываешь его в all0001.txt

потом для каждого new.txt делаешь в цикле проход как-то так:

for i in all????.txt; do
   grep -F -v -f $i new.txt > new_wo_dub.txt
   mv new_wo_dub.txt new.txt
done
dikiy ★★☆☆☆
()
Ответ на: комментарий от Sma11erM1nd

И будет ли он брать первый файл из каталога new и сравнивать со всеми из каталога all

если я правильно понял, то простой bash скрипт с diff тебе поможет.

dada ★★★★★
()

Медленно, но память почти не должно потреблять

while read -r line
  do grep --quiet -F ${line} all_data || echo ${line} >> new_uniques
done < new_data
echo new_uniques >> all_data
rm new_uniques
urquan
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.