Как найти повторяющиеся строки в очень больших (65 ГБ) текстовых файлах?

У меня есть 10 текстовых файлов, каждая строка которых содержит 65 символов шестнадцатеричного значения. Каждый текстовый файл имеет размер 6,5 ГБ (99999999 строк).

то есть file1-6.5GB, file2-6.5GB, file3-6.5GB, file4-6.5GB, ... file10-6.5GB

Мне нужно найти повторяющиеся строки во всех этих 10 текстовых файлах вместе, и мне нужно знать, какая повторяющаяся строка взята из какого файла и сколько файлов имеют повторяющиеся строки?

Как я могу это сделать?

В настоящее время я использую эту команду:

      sort *.txt | uniq -d > dup

Но зависает, а иногда и вылетает. Если я хочу проверить файл размером 65 ГБ, нужно ли мне в два раза больше памяти компьютера, т.е. нужно ли мне устанавливать больше памяти?

Есть ли другой способ сделать это?

1 ответ

Предполагая сортировку GNU

sortне требует объема оперативной памяти больше или даже равного размеру обрабатываемых файлов, он использует доступную память и временные файлы во время обработки для сортировки больших файлов в пакетах. Это очень эффективно и делает это без необходимости вмешательства пользователя при чтении непосредственно из файла/ов. Однако при чтении из канала или STDIN установка значения размера буфера с опцией --buffer-size=SIZEможет понадобиться для эффективности.

Так что вам, скорее всего, нужно достаточно места на диске, которое можно свободно использовать под /tmp... если места на диске недостаточно, вы можете попробовать --compress-program=PROGвариант ( PROGэто программа сжатия, которая будет использоваться как gzip. Вам нужно указать это, и он должен быть установлен в вашей системе) , чтобы сжимать и распаковывать временные файлы во время процесса сортировки следующим образом:

      sort --compress-program=gzip *.txt | uniq -d > dupfile

Сбои, скорее всего, происходят из-за параллельного использования большего количества потоков/процессов обработки, чем ваша система может обрабатывать одновременно. Вы можете ограничить это, чтобы уменьшить нагрузку на систему, используя --parallel=Nвариант ( Nможет быть число из 1к 8. Чем меньше число, тем медленнее обработка, но нагрузка на систему также будет ниже, и сбои прекратятся) вот так:

      sort --parallel=2 *.txt | uniq -d > dupfile

Эти два параметра также можно использовать вместе, например:

      sort --compress-program=gzip --parallel=2 *.txt | uniq -d > dupfile

Кроме того, вы можете сделать это в два шага: сначала предварительно отсортировать файлы один за другим, а затем использовать --mergeопция для уже отсортированных файлов, чтобы объединить файлы без сортировки следующим образом:

      sort --merge *.txt | uniq -d > dupfile

И, конечно же, вы можете использовать все три параметра для предварительно отсортированных файлов, чтобы уменьшить нагрузку на вашу систему, например:

      sort --compress-program=gzip --parallel=2 --merge  *.txt | uniq -d > dupfile

Чтобы узнать, какие повторяющиеся строки пришли из какого файла / файлов , вы можете использовать grepс -Fвариант, который будет обрабатывать целые строки как фиксированные строки и должен дать вам больше производительности и вариант -xкоторый будет точно соответствовать всей строке следующим образом:

      grep -Fx -f dupfile *.txt > resultfile
Другие вопросы по тегам