Как объединить огромное количество файлов

Я хотел бы объединить свои файлы. я использую

cat *txt > newFile

Но у меня почти 500000 файлов и он жалуется, что

argument list is too long.

Есть ли эффективный и быстрый способ объединить полмиллиона файлов?

Спасибо


person user1007742    schedule 09.09.2013    source источник


Ответы (2)


Если ваша структура каталогов неглубокая (нет подкаталогов), вы можете просто сделать:

find . -type f -exec cat {} \; > newFile

Если у вас есть подкаталоги, вы можете ограничить поиск верхним уровнем или рассмотреть возможность размещения некоторых файлов в подкаталогах, чтобы не возникало этой проблемы!

Это не особенно эффективно, и некоторые версии find позволяют:

find . -type f -exec cat {} \+ > newFile

для большей эффективности. (Обратите внимание, что обратная косая черта перед + не обязательна, но мне кажется, что это хорошо для симметрии с предыдущим примером.)

person William Pursell    schedule 09.09.2013
comment
Спасибо. Где указать расширение файла? я не хочу кошачьи все, а только определенные файлы (например, * txt). У меня нет подкаталогов. - person user1007742; 09.09.2013
comment
Вы можете ограничить поиск с помощью -name. Например, если вам нужны только файлы .txt, используйте find . -name '*.txt' .... Подробности смотрите в документации по find. - person William Pursell; 09.09.2013
comment
сравнение предложенного подхода с for i in ls;do cat $i >> newFile по 10 files каждому 10GB дает 50 seconds прибыли последнему подходу; тестовый пример, выполненный на сервере с одним узлом (2.1 GHz, single processor; Intel Xeon, 4 cores). - person knowone; 18.06.2018
comment
обратите внимание, что это решение не объединяет файлы в каком-то предикативном порядке, не говоря уже о том, что в том же порядке, что и расширение вопроса с подстановочными знаками в оболочке. - person db-inf; 11.12.2020

Как насчет того, чтобы сделать это в цикле:

for a in *.txt ; do cat $a >> newFile ; done

Недостатком этого является создание нового экземпляра cat для каждого файла, что может быть дорогостоящим, но если файлы достаточно велики, накладные расходы ввода-вывода должны доминировать над временем ЦП, необходимым для создания нового процесса.

Я бы порекомендовал создать файл, содержащий файлы в правильном порядке, я не уверен на 100% в гарантиях использования таких подстановок (и таких, как в вопросе).

person unwind    schedule 09.09.2013
comment
Я бы рекомендовал этот подход для слияния больших файлов; немного быстрее, чем cat при использовании с find. - person knowone; 18.06.2018
comment
Я бы предложил разместить перенаправление на новый файл после цикла, чтобы процессу не приходилось искать конец нового файла на каждой итерации. Вот так: for a in *.txt ; do cat $a; done > newFile - person db-inf; 11.12.2020