Cara menambahkan konten beberapa file ke dalam satu file

174

Saya ingin menyalin isi dari lima file ke satu file apa adanya. Saya mencoba melakukannya menggunakan cp untuk setiap file. Tapi itu menimpa konten yang disalin dari file sebelumnya. Saya juga mencoba

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

dan itu tidak berhasil.

Saya ingin skrip saya menambahkan baris baru di akhir setiap file teks.

misalnya. File 1.txt, 2.txt, 3.txt. Masukkan konten 1,2,3 ke dalam 0.txt

Bagaimana saya melakukannya ?

Uap
sumber
1
duplikat yang mungkin dari File Penggabungan Dan Sisipkan Baris Baru Di Antara File
Nikos C.
Jawaban lain di sini: stackoverflow.com/questions/2576693/…
Nikos C.

Jawaban:

308

Anda memerlukan perintah cat(kependekan untuk concatenate), dengan pengalihan shell ( >) ke file output Anda

cat 1.txt 2.txt 3.txt > 0.txt
radikal7
sumber
8
seharusnya >> benar? dan juga mengapa ada baris baru sebelum semua teks dalam file 0.txt saya?
Uap
1
apakah Anda ingin mempertahankan konten 0.txt?
lihat
13
@blasto tergantung. Anda akan menggunakan >>untuk menambahkan satu file ke file lain, di mana > menimpa file output dengan apa pun yang diarahkan ke dalamnya. Sedangkan untuk baris baru, apakah ada baris baru sebagai karakter pertama dalam file 1.txt? Anda dapat mengetahuinya dengan menggunakan od -c, dan melihat apakah karakter pertama adalah a \n.
radical7
1
@ radical7 Terima kasih. Sebenarnya, file saya seperti foo_1, foo_2, foo_3. Saya mencoba mengubah kode Anda sebagai - cat "$ filename _" {1,2,3} ". Txt", tetapi tidak berhasil.
Steam
1
@blasto Anda pasti menuju ke arah yang benar. Bash tentu saja menerima formulir {...}untuk pencocokan nama file, jadi mungkin tanda kutunya sedikit mengacaukan skrip Anda? Saya selalu mencoba bekerja dengan hal-hal seperti ini menggunakan lsshell. Ketika saya mendapatkan perintah dengan benar, saya hanya memotong-n-tempelkan ke skrip apa adanya. Anda juga mungkin menemukan -xopsi ini berguna dalam skrip Anda - itu akan menggemakan perintah yang diperluas dalam skrip sebelum eksekusi.
radical7
97

Pilihan lain, bagi Anda yang masih menemukan posting ini seperti yang saya lakukan, adalah menggunakan find -exec:

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

Dalam kasus saya, saya membutuhkan opsi yang lebih kuat yang akan memeriksa banyak subdirektori sehingga saya memilih untuk menggunakannya find. Hancurkan:

find .

Lihat di dalam direktori kerja saat ini.

-type f

Hanya tertarik pada file, bukan direktori, dll.

-name '*.txt'

Kurangi hasil yang ditentukan nama

-exec cat {} +

Jalankan perintah cat untuk setiap hasil. "+" berarti hanya 1 instance dari catspawned (thx @gniourf_gniourf)

 >> output.file

Seperti dijelaskan dalam jawaban lain, tambahkan konten cat-ed ke akhir file output.

mopo922
sumber
10
Ada banyak kekurangan dalam jawaban ini. Pertama, wildcard *.txtharus dikutip (jika tidak, seluruh findperintah, seperti yang tertulis, tidak berguna). Kelemahan lain datang dari kesalahpahaman kotor: perintah yang dieksekusi bukan cat >> 0.txt {} , tapi cat {}. Perintah Anda sebenarnya setara dengan { find . -type f -name *.txt -exec cat '{}' \; ; } >> 0.txt(saya menambahkan pengelompokan sehingga Anda menyadari apa yang sebenarnya terjadi). Kelemahan lain findadalah akan menemukan file 0.txt, dan catakan mengeluh dengan mengatakan bahwa file input adalah file output .
gniourf_gniourf
Terima kasih atas koreksinya. Kasing saya sedikit berbeda dan saya belum memikirkan beberapa gotcha seperti yang diterapkan pada kasing ini.
mopo922
Anda harus meletakkan >> output.filedi akhir perintah Anda, sehingga Anda tidak membujuk siapa pun (termasuk diri Anda) untuk berpikir yang findakan mengeksekusi cat {} >> output.fileuntuk setiap file yang ditemukan.
gniourf_gniourf
Mulai terlihat sangat bagus! Satu saran terakhir: gunakan -exec cat {} +alih-alih -exec cat {} \;, sehingga hanya satu instance dari catyang dihasilkan dengan beberapa argumen ( +ditentukan oleh POSIX ).
gniourf_gniourf
3
Jawaban dan kata peringatan yang baik - Saya memodifikasi milik saya menjadi: find . -type f -exec cat {} + >> outputfile.txtdan tidak bisa mengetahui mengapa file output saya tidak akan berhenti tumbuh menjadi pertunjukan walaupun direktori hanya 50 MB. Itu karena saya terus menambahkan outputfile.txt ke dirinya sendiri! Jadi pastikan untuk memberi nama file itu dengan benar atau letakkan di direktori lain sepenuhnya untuk menghindari ini.
Thisisstackoverflow
43

jika Anda memiliki tipe output tertentu maka lakukan sesuatu seperti ini

cat /path/to/files/*.txt >> finalout.txt
Eswar Yaganti
sumber
1
Perlu diingat bahwa Anda kehilangan kemungkinan untuk mempertahankan pesanan gabungan. Ini dapat mempengaruhi Anda jika Anda memiliki nama file Anda, mis. file_1,, file_2file_11, Karena urutan alami bagaimana file diurutkan.
emix
16

Jika semua file Anda berada dalam direktori tunggal, Anda bisa melakukannya

cat * > 0.txt

File 1.txt, 2.txt, .. akan masuk ke 0.txt

Pooja
sumber
Sudah dijawab oleh Eswar. Perlu diingat bahwa Anda kehilangan kemungkinan untuk mempertahankan pesanan gabungan. Ini dapat mempengaruhi Anda jika Anda memiliki nama file Anda, mis. file_1,, file_2file_11, Karena urutan alami bagaimana file diurutkan.
emix
10
for i in {1..3}; do cat "$i.txt" >> 0.txt; done

Saya menemukan halaman ini karena saya harus menggabungkan 952 file menjadi satu. Saya menemukan ini berfungsi lebih baik jika Anda memiliki banyak file. Ini akan melakukan perulangan untuk berapa banyak angka yang Anda butuhkan dan cat masing-masing menggunakan >> untuk menambahkan ke akhir 0.txt.

freddythunder
sumber
Anda bisa menggunakan brace expansion dalam bash untuk menulis cat {1,2,3} .txt >> 0.txt
mcheema
9

Jika semua file Anda dinamai serupa, Anda bisa melakukannya:

cat *.log >> output.log
AeaRy
sumber
5

Pilihan lain adalah sed:

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

Atau...

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

Atau...

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

Atau tanpa pengalihan ...

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

Perhatikan bahwa baris terakhir tulis juga merge.txt(tidak wmerge.txt!). Anda dapat menggunakan w"merge.txt"untuk menghindari kebingungan dengan nama file, dan -nuntuk output diam.

Tentu saja, Anda juga dapat mempersingkat daftar file dengan wildcard. Misalnya, dalam kasus file bernomor seperti dalam contoh di atas, Anda dapat menentukan rentang dengan kurung dengan cara ini:

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

jika file Anda berisi tajuk dan Anda ingin menghapusnya di file output, Anda dapat menggunakan:

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

Jika file asli berisi karakter yang tidak dapat dicetak, mereka akan hilang saat menggunakan perintah cat. Menggunakan 'cat -v', non-printable akan dikonversi ke string karakter yang terlihat, tetapi file output masih tidak mengandung karakter non-printable yang sebenarnya dalam file asli. Dengan sejumlah kecil file, alternatifnya mungkin dengan membuka file pertama dalam editor (misalnya vim) yang menangani karakter yang tidak dicetak. Kemudian manuver ke bagian bawah file dan masukkan ": r second_file_name". Itu akan menarik file kedua, termasuk karakter non-cetak. Hal yang sama dapat dilakukan untuk file tambahan. Ketika semua file telah dibaca, masukkan ": w". Hasil akhirnya adalah bahwa file pertama sekarang akan berisi apa yang ia lakukan semula, ditambah konten dari file yang dibaca.

BACooper
sumber
Ini sangat tidak bisa skrip.
FKEinternet
1

Jika Anda ingin menambahkan konten 3 file ke dalam satu file, maka perintah berikut akan menjadi pilihan yang baik:

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

Ini akan menggabungkan konten semua file ke file4, melempar output konsol /dev/null.

Ajit K'sagar
sumber