Объединять текстовые файлы, разделяя их новой строкой - PullRequest
0 голосов
/ 09 сентября 2018

У меня чуть более 100 текстовых файлов в каталоге, функционирующих как простая база данных, каждая строка которой содержит одну запись. В общей сложности эти файлы составляют около 25 ГБ. Однако записи не сортируются по алфавиту и их много, поэтому для того, чтобы алфавитизировать содержимое всех ~ 100 текстовых файлов, используя что-то вроде sort -u, я сначала пытаюсь объединить все эти файлы в один большой текст файл. Простой cat был бы неподходящим, потому что начало и конец 100 текстовых файлов не содержат новых строк, что (на мой взгляд) приведет к объединению последней записи в файле с первой записью следующего файла.

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

Ответы [ 4 ]

0 голосов
/ 10 сентября 2018

sort * должно быть всем, что вам нужно, но на всякий случай вам нужно добавить новые строки в содержимое файла для обработки последующим инструментом, вот как это сделать:

$ ls
file1  file2
$ cat file1
foo$
$ cat file2
bar$
$ cat file1 file2
foobar$

$ find . -type f -exec sh -c '(cat {}; printf "\\n")' \;
foo
bar

Это, конечно, при условии, что ваш cat может обрабатывать файлы, которые не заканчиваются символами новой строки!

0 голосов
/ 09 сентября 2018

Вы можете использовать awk.

$ od -t x1 file1
0000000 72 65 63 6f 72 64 31 0a 72 65 63 6f 72 64 32
0000017
$ od -t x1 file2
0000000 72 65 63 6f 72 64 31 0a 72 65 63 6f 72 64 32 0a
0000020 72 65 63 6f 72 64 33
0000027
$ awk 1 file1 file2
record1
record2
record1
record2
record3

1 здесь скрипт awk, что означает печать всех записей

0 голосов
/ 10 сентября 2018

Простой

sort -u *.db > uniquified # adjust glob as needed

должен это сделать;sort будет вставлять новые строки между файлами, если это будет необходимо.

cat *.db | sort -u

- это классический UUoC , и проблема с файлами, в которых отсутствуют завершающие символы новой строки, - не единственная проблема.

Сказав это, 25 ГБ, вероятно, не поместится в вашей оперативной памяти, поэтому sort в конечном итоге приведет к созданию временных файлов.Может оказаться быстрее отсортировать файлы в четыре или пять групп, а затем объединить результаты.Это могло бы лучше использовать большое количество дубликатов.Но я бы только экспериментировал, если бы простая команда действительно занимала непомерное количество времени.

Несмотря на это, сортировка файлов по отдельности, вероятно, еще медленнее;обычно лучшим вариантом является максимальное использование ресурсов памяти для каждого вызова sort.Например, вы можете использовать xargs с опцией -n, чтобы разбить список файлов на группы по пару десятков файлов в каждой.После сортировки каждой группы вы можете использовать sort -m для объединения отсортированных временных файлов.

Несколько замечаний о том, как улучшить скорость сортировки:

  1. Использование LC_COLLATE=C sort, если вам не нужна сортировка буквенных данных с учетом локали.Обычно это ускоряет сортировку в три-четыре раза.

  2. Избегайте использования RAM-дисков для временного пространства.(Во многих дистрибутивах Linux /tmp является диском ОЗУ.) Поскольку sort использует временные диски, когда у него заканчивается ОЗУ, размещение временного диска в RAM-диске неэффективно.По той же причине не помещайте свои собственные временные выходные файлы в /tmp./var/tmp должен быть реальный диск;еще лучше, если это возможно, использовать второй дисковод (конечно, не медленный USB-накопитель).

  3. Избегайте чрезмерной подкачки вашей машины во время сортировки,выключив swap:

    sudo swapoff -a
    

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

  4. В идеале нужно настроить -S таким образом, чтобы sort использовал столько памяти, сколько вы можете сэкономить, и избегал использования внутренних временных файлов, сортируя куски, которые помещаются в этот объем памяти.(Объединение отсортированных чанков происходит намного быстрее, чем сортировка, и оно читает и записывает последовательно, не занимая дополнительное место на диске.) Вам, вероятно, придется провести некоторые эксперименты, чтобы найти хороший размер чанка.

0 голосов
/ 09 сентября 2018

Я бы посоветовал вам создать этот файл, объединяя все входные файлы и вставляя новую строку посередине:

out=newfile.txt
rm -f "$out"
for f in *.txt
do
    cat "$f" >> "$out"
    echo >> "$out"
done

Теперь вы можете сортировать это. Или удалите пустые строки, если вы думаете, что может быть некоторый входной файл с новой строкой в ​​конце.

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