Як додати вміст декількох файлів в один файл


174

Я хочу скопіювати вміст п'яти файлів в один файл таким, яким є. Я спробував це зробити за допомогою cp для кожного файлу. Але це перезаписує вміст, скопійований з попереднього файлу. Я також спробував

paste -d "\n" 1.txt 0.txt

і не вийшло.

Я хочу, щоб мій сценарій додав новий рядок в кінці кожного текстового файлу.

напр. Файли 1.txt, 2.txt, 3.txt. Вмістіть 1,2,3 в 0.txt

Як це зробити?


1
можливий дублікат об'єднаних файлів і вставити новий рядок між файлами
Nikos C.

Ще одна відповідь тут: stackoverflow.com/questions/2576693/…
Нікос К.

Відповіді:


308

Вам потрібна команда cat(короткий для з'єднання) з перенаправленням оболонки ( >) у вихідний файл

cat 1.txt 2.txt 3.txt > 0.txt

8
має бути >> правда? а також чому є новий рядок перед усім текстом у моєму файлі 0.txt?
Steam

1
Ви хочете зберегти вміст 0.txt?
sehe

13
@blasto це залежить. Ви використовуєте >>для додавання одного файлу до іншого, де > перезаписуєте вихідний файл із тим, що спрямовано в нього. Що стосується нового рядка, чи є новий рядок як перший символ у файлі 1.txt? Ви можете дізнатися, скориставшись od -cі побачивши, чи є перший символ а \n.
радикальний7

1
@ радикал7 Дякую Насправді мої файли схожі на foo_1, foo_2, foo_3. Я спробував змінити ваш код як - cat "$ filename _" {1,2,3} ". Txt", але це не вийшло.
Steam

1
@blasto Ви неодмінно рухаєтесь у правильному напрямку. Bash, безумовно, приймає форму {...}для відповідності імені файлів, тому, можливо, цитати зіпсували щось у вашому сценарії? Я завжди намагаюся працювати з такими речами, використовуючи lsоболонку. Коли я отримаю команду правильно, я просто вирізаю-вставте її в сценарій як є. Ви також можете знайти -xваріант, корисний у своїх сценаріях - він повторюватиме розширені команди у скрипті перед виконанням.
радикал7

97

Іншим варіантом для тих, хто все ще натрапляє на цю посаду, як я, є використання find -exec:

find . -type f -name '*.txt' -exec cat {} + >> output.file

У моєму випадку мені знадобився більш надійний варіант, який би переглядав кілька підкаталогів, тому я вирішив використовувати find. Розбийте його:

find .

Загляньте в поточний робочий каталог.

-type f

Цікавлять лише файли, а не каталоги тощо.

-name '*.txt'

Збийте результат, встановлений назвою

-exec cat {} +

Виконайте команду cat для кожного результату. "+" означає, що catпороджується лише 1 екземпляр (thx @gniourf_gniourf)

 >> output.file

Як пояснено в інших відповідях, додайте змішаний код до кінця вихідного файлу.


10
У цій відповіді багато недоліків. По-перше, *.txtпотрібно вказати підстановку (інакше вся findкоманда, як написано, марна). Ще одна вада походить від грубої помилки: команда, яка виконується , не cat >> 0.txt {} , але cat {}. Ваша команда насправді еквівалентна { find . -type f -name *.txt -exec cat '{}' \; ; } >> 0.txt(я додав групування, щоб ви зрозуміли, що насправді відбувається). Ще один недолік полягає в тому, що findзбирається знайти файл 0.txt, і catскаржиться, кажучи, що вхідний файл є вихідним файлом .
gniourf_gniourf

Дякуємо за виправлення. Мій випадок був дещо іншим, і я не думав про деякі з цих припадків, що стосуються цієї справи.
mopo922

Вам слід поставити >> output.fileв кінці вашої команди, щоб ви нікого не наштовхували на думки, які findбудуть виконуватись cat {} >> output.fileдля кожного знайденого файлу.
gniourf_gniourf

Починаючи виглядати дійсно добре! Одне заключне пропозиція: використовувати -exec cat {} +замість -exec cat {} \;, щоб лише один екземпляр catпородився кількома аргументами ( +задається POSIX ).
gniourf_gniourf

3
Хороша відповідь і слово попередження - я змінив шаблону на: find . -type f -exec cat {} + >> outputfile.txtі не міг зрозуміти, чому мій вихідний файл не перестане переростати в концерти, навіть якщо в каталозі було всього 50 мег. Це було тому, що я продовжував додавати outputfile.txt до себе! Тому просто переконайтеся, що правильно назви цей файл або повністю помістити його в інший каталог, щоб уникнути цього.
Thisisstackoverflow

43

якщо у вас є певний тип виводу, тоді зробіть щось подібне

cat /path/to/files/*.txt >> finalout.txt

1
Майте на увазі, що ви втрачаєте можливість підтримувати порядок злиття. Це може вплинути на вас, якщо у вас є імена файлів, наприклад. file_1,, file_2file_11, Через природний порядок сортування файлів.
emix

16

Якщо всі ваші файли в одному каталозі, ви можете просто зробити

cat * > 0.txt

Файли 1.txt, 2.txt, .. перейдуть у 0.txt


Вже відповів Есвар. Майте на увазі, що ви втрачаєте можливість підтримувати порядок злиття. Це може вплинути на вас, якщо у вас є імена файлів, наприклад. file_1,, file_2file_11, Через природний порядок сортування файлів.
емікс

10
for i in {1..3}; do cat "$i.txt" >> 0.txt; done

Я знайшов цю сторінку, тому що мені потрібно було об'єднати 952 файли разом в один. Я виявив, що це працює набагато краще, якщо у вас багато файлів. Це зробить цикл для будь-якої кількості потрібних вам цифр і підкресліть кожне, використовуючи >>, щоб додати його до кінця 0.txt.


ви можете використовувати розширення дужок у bash, щоб написати cat {1,2,3} .txt >> 0.txt
mcheema

9

Якщо всі ваші файли названі так само, ви можете просто зробити:

cat *.log >> output.log

5

Ще один варіант sed:

sed r 1.txt 2.txt 3.txt > merge.txt 

Або ...

sed h 1.txt 2.txt 3.txt > merge.txt 

Або ...

sed -n p 1.txt 2.txt 3.txt > merge.txt # -n is mandatory here

Або без перенаправлення ...

sed wmerge.txt 1.txt 2.txt 3.txt

Зауважте, що останній рядок також пишете merge.txt(не wmerge.txt!). Ви можете використовувати w"merge.txt"для уникнення плутанини з назвою файлу та -nдля безшумного виводу.

Звичайно, ви також можете скоротити список файлів за допомогою символів. Наприклад, у випадку нумерованих файлів, як у наведених вище прикладах, ви можете вказати діапазон за допомогою дужок таким чином:

sed -n w"merge.txt" {1..3}.txt

4

якщо ваші файли містять заголовки, і ви хочете видалити їх у вихідному файлі, ви можете використовувати:

for f in `ls *.txt`; do sed '2,$!d' $f >> 0.out; done

3

Якщо оригінальний файл містить символи, що не надруковані, вони будуть втрачені при використанні команди cat. Використовуючи 'cat -v', недруковані файли будуть перетворені у видимі рядки символів, але вихідний файл все одно не міститиме фактичних символів, що не надруковані у вихідному файлі. З невеликою кількістю файлів альтернативою може бути відкриття першого файлу в редакторі (наприклад, vim), який обробляє символи, що не друкуються. Потім виконайте маневр у нижній частині файлу та введіть ": r second_file_name". Це потягне за собою другий файл, включаючи символи, що не друкуються. Те ж саме можна зробити і для додаткових файлів. Коли всі файли будуть прочитані, введіть ": w". Кінцевим результатом є те, що перший файл тепер буде містити те, що він робив спочатку, а також вміст файлів, які були прочитані.


Це не дуже можливо.
FKEinternet

1

Якщо ви хочете додати вміст 3-х файлів до одного файлу, то наступна команда стане хорошим вибором:

cat file1 file2 file3 | tee -a file4 > /dev/null

Він об'єднає вміст усіх файлів у file4, передаючи консольний вихід /dev/null.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.