Объединение нескольких текстовых файлов в один файл в Bash

229

Каков самый быстрый и самый прагматичный способ объединить все *.txt файл в каталог в один большой текстовый файл?

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

Командная оболочка Windows тоже будет хороша, но я сомневаюсь, что она есть.

Теги:

9 ответов

399
Лучший ответ

Это добавляет вывод в файл all.txt

cat *.txt >> all.txt

Это перезаписывает all.txt

cat *.txt > all.txt
  • 26
    Вы можете столкнуться с проблемой, когда он переворачивает all.txt в all.txt ... У меня иногда возникает эта проблема с grep, я не уверен, что cat имеет такое же поведение.
  • 8
    @ rmeador да, это правда, если all.txt уже существует, у вас будет эта проблема. Эта проблема решается путем предоставления выходного файла с другим расширением или перемещения all.txt в другую папку.
Показать ещё 7 комментариев
107

Просто помните, что для всех решений, предоставленных до сих пор, оболочка решает порядок, в котором файлы объединены. Для Bash, IIRC, этот алфавитный порядок. Если порядок важен, вы должны либо соответствующим образом указать файлы (01file.txt, 02file.txt и т.д.), Либо указать каждый файл в том порядке, в котором вы хотите его соединить.

$ cat file1 file2 file3 file4 file5 file6 > out.txt
29

Команда оболочки Windows type может сделать это:

type *.txt >outputfile

Команда type также записывает имена файлов в stderr, которые не записываются оператором перенаправления > (но будет отображаться на консоли).

  • 6
    +1 за нативное решение
  • 2
    Просто имейте в виду, что если вы поместите выходной файл в тот же каталог, что и исходный файл, это приведет к дублированию, так как он также объединит новый выходной файл дважды.
22

Оболочку оболочки copy можно использовать для конкатенации файлов.

C:\> copy *.txt outputfile

С помощью:

Чтобы добавить файлы, укажите один файл для назначения, но несколько файлов для источника (с использованием подстановочных знаков или файлов1 + файл2 + формат файла3).

  • 0
    Это, как самое чистое решение IMHO, практически без побочных эффектов, которые могут запутать новички, к сожалению, недостаточно оценивается :-(
  • 0
    ОП попросил Баш.
Показать ещё 1 комментарий
4

наиболее прагматичным способом с оболочкой является команда cat. другие способы включают,

awk '1' *.txt > all.txt
perl -ne 'print;' *.txt > all.txt
  • 2
    perl -pe 1 *.txt > all.txt
  • 0
    Это должно быть правильным ответом для большинства обстоятельств. Если какой-либо текстовый файл без пустой новой строки, используя все вышеописанные методы, cat объединит последнюю строку и первую строку из смежных файлов.
3
type [source folder]\*.[File extension] > [destination folder]\[file name].[File extension]

Пример:

type C:\*.txt > C:\1\all.txt

Это возьмет все файлы txt в папке C:\и сохранит его в папке C:\1 по имени all.txt

или

type [source folder]\* > [destination folder]\[file name].[File extension]

Пример:

type C:\* > C:\1\all.txt

Это займет все файлы, которые присутствуют в папке, и поместите туда содержимое в C:\1\all.txt

2

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

for i in $(ls | grep ".txt");do cat $i >> output.txt;done

РЕДАКТИРОВАТЬ: Как кто-то сказал в комментариях, вы можете заменить $(ls | grep ".txt") на $(ls *.txt)

РЕДАКТИРОВАТЬ: благодаря опыту @gnourf_gnourf, использование glob является правильным способом перебора файлов в каталоге. Следовательно, кощунственные выражения типа $(ls | grep ".txt") должны быть заменены на *.txt (см. Статью здесь).

Хорошее решение

for i in *.txt;do cat $i >> output.txt;done
  • 1
    Почему не for i in $(ls *.txt);do cat $i >> output.txt;done ?
  • 1
    Обязательная ссылка ParsingLs вместе с понижающим голосом (и вы заслуживаете более одного понижающего голоса, потому что ls | grep - серьезный плохой антипаттерн).
Показать ещё 2 комментария
2

Как насчет этого подхода?

find . -type f -name '*.txt' -exec cat {} + >> output.txt
  • 0
    Так как OP говорит, что файлы находятся в одном каталоге, вам может понадобиться добавить -maxdepth 1 к команде find .
  • 0
    Прекрасно работает с большим количеством файлов, где подход принятого ответа терпит неудачу
-5

все это неприятно....

ls | grep *.txt | while read file; do cat $file >> ./output.txt; done;

легкий материал.

  • 6
    EEEK! Не делай этого. find . -iname "*.txt" -maxdepth 1 -exec cat {} >> out.txt \;
  • 6
    Для тех, кто интересуется, почему бы не сделать это: mywiki.wooledge.org/ParsingLs

Ещё вопросы

Сообщество Overcoder
Наверх
Меню