shell - cat - объединить содержимое файлов в один большой файл

Я пытаюсь с помощью bash объединить содержимое списка файлов (более 1 КБ) в большой файл.

Я пробовал следующую команду cat:

cat * >> bigfile.txt

однако эта команда объединяет все, включая уже объединенные.

например файл1.txt

content1

файл2.txt

content2

файл3.txt

content3

файл4.txt

content4

большой файл.txt

content1
content2
content3
content2
content3
content4
content2

но я хотел бы просто

content1
content2
content3
content4

внутри .txt файла

Другим способом было бы cat file1.txt file2.txt ... и так далее... но я не могу сделать это для более чем 1k файлов!

Спасибо за Вашу поддержку!


person fabioln79    schedule 24.05.2012    source источник


Ответы (6)


Проблема в том, что вы помещаете bigfile в тот же каталог, что делает его частью *. Так что-то вроде

cat dir/* > bigfile

должен работать так, как вы этого хотите, с вашими fileN.txt файлами, расположенными в dir/

person mvds    schedule 24.05.2012
comment
Я думаю, что fabioln намеренно включает bigfile.txt во входные данные; он хочет добавить в файл из разных file*.txt, но убрав при этом дубликаты. - person chepner; 24.05.2012
comment
Спасибо вам, ребята. Да, это была проблема! Я поместил большой файл в тот же каталог... поэтому я использовал команду, которую вы мне дали (cat dir/* › bigfile)! Только еще вопрос: почему вы поставили просто › вместо ›› это то же самое? Спасибо! - person fabioln79; 24.05.2012
comment
@fabioln79, используя >>, вы добавляете вывод в файл, используя >, вы перезаписываете все содержимое. - person mvds; 25.05.2012
comment
Всегда ли можно полагаться на звездную нотацию для объединения файлов в правильном порядке? - person Chris K; 20.04.2017
comment
Зависит от вашего правильного порядка; оболочка раскроет * в алфавитном порядке, см. serverfault.com/a/122743 - person mvds; 20.04.2017

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

shopt -s extglob
cat !(bigfile.txt) > bigfile.txt
person glenn jackman    schedule 24.05.2012
comment
Спасибо. У меня есть вопрос, связанный с этой командой: каталог, содержащий файл, имеет размер 557 ГБ, однако созданный большой файл имеет размер 495. Я не знаю, как это объяснить. Я делаю что-то не так? Спасибо! - person fabioln79; 25.05.2012
comment
@ fabioln79 Учитывая количество предоставленной информации, подозреваю, что это может быть связано с фактически используемым пространством и размером блока (прочитайте о последнем) - person user66001; 28.07.2014

При повторном прочтении вашего вопроса кажется, что вы хотите добавить данные в bigfile.txt, но без добавления дубликатов. Вам придется пропустить все через sort -u, чтобы отфильтровать дубликаты:

sort -u * -o bigfile.txt

Параметр -o для сортировки позволяет безопасно включать содержимое bigfile.txt во входные данные для сортировки до того, как файл будет перезаписан выходными данными.

РЕДАКТИРОВАТЬ: Предполагая, что bigfile.txt отсортирован, вы можете попробовать двухэтапный процесс:

sort -u file*.txt | sort -um - bigfile.txt -o bigfile.txt

Сначала мы сортируем входные файлы, удаляя дубликаты. Мы передаем этот вывод другому процессу sort -u, который также использует параметр -m, который сообщает sort объединить два ранее отсортированных файла. Мы объединим два файла: - (стандартный ввод, поток исходит из первого sort) и сам bigfile.txt. Мы снова используем параметр -o, чтобы позволить нам записать вывод обратно в bigfile.txt после того, как мы прочитали его как ввод.

person chepner    schedule 24.05.2012
comment
Я изменил ответ, чтобы разрешить объединение новых данных в bigfile.txt таким образом, чтобы они оставались отсортированными без добавления дубликатов. Я думаю, что это лучшее, что вы можете сделать, не переключаясь на более структурированный формат (например, базу данных). - person chepner; 24.05.2012

Другим способом будет cat file1.txt file2.txt ... и так далее ... но я не могу сделать это для более чем 1k файлов!

Вот для чего нужен xargs:

find . -maxdepth 1 -type f -name "file*.txt" -print0 | xargs -0 cat > bigfile.txt
person Barton Chittenden    schedule 24.05.2012
comment
xargs выполняет команду для каждого аргумента? Если да, следует ли использовать «››» вместо «›»? Я думаю, что когда это будет сделано, bigfile.txt будет содержать только содержимое последнего переданного ему файла. - person JerseyMike; 24.05.2012
comment
xargs запускает команду один раз для всех аргументов, вам не нужно использовать '>>'. - person Barton Chittenden; 24.05.2012
comment
Спасибо за разъяснение. Страница руководства не была мне очень понятна. - person JerseyMike; 24.05.2012

Это старый вопрос, но все же я дам другой подход с xargs

  1. #P2# <блочная цитата> #P3#
  2. Проверьте правильность порядка файлов с помощью vi или cat. Если вы используете суффикс (1, 2, 3, ..., N), это не должно быть проблемой.

  3. #P5# <блочная цитата> #P6#
  4. #P7# <блочная цитата> #P8#

Надеюсь, это поможет кому-нибудь

person Alwin Kesler    schedule 07.11.2014

Пытаться:

cat `ls -1 *` >> bigfile.txt

У меня нет под рукой Unix-машины, чтобы сначала протестировать ее для вас.

person JerseyMike    schedule 24.05.2012
comment
-1 Это ничего не решает, а привносит какие-то свои проблемы. Не используйте ls, когда подстановочный знак уже расширяется до нужных вам файлов! Не используйте имена файлов без кавычек (вывод из обратных кавычек), потому что это прерывается, если имена файлов содержат пробелы. - person tripleee; 24.05.2012
comment
На самом деле я думал о цикле, когда писал это, но это не пришло мне в голову должным образом. В любом случае мне больше нравится ответ Бартона. - person JerseyMike; 24.05.2012