Bagaimana cara menambahkan satu file ke file lain di Linux dari shell?

418

Saya punya dua file: file1dan file2. Bagaimana cara menambahkan isi file2ke file1sehingga isi file1bertahan proses?

asir
sumber

Jawaban:

611

Gunakan pengalihan bawaan bash (tldp) :

cat file2 >> file1
David
sumber
2
Bagaimana Anda melakukannya file tujuan tidak dimiliki oleh Anda dan Anda perlu menggunakan sudo?
Bijay Rungta
1
@BijayRungta: Sepertinya Anda menjawab pertanyaan Anda sendiri. Anda akan pra-Pend sudoke catperintah (dan masukkan kredensial jika diminta).
David
Anda perlu ... chmod 777 / etc / default / docker untuk memberi diri Anda izin menulis pada file itu - pastikan untuk mengembalikan izin file lama setelah selesai
danday74
1
@ Konfigurasi: Kecuali jika ada cara untuk mengarahkan output ke dua file sekaligus, itu akan melibatkan dua pemanggilan perintah.
David
2
@Sigur atau lihat di teeProgram: cat 1 | tee -a 2 3. Anda dapat menempatkan file sebanyak yang Anda suka setelah saklar --append(atau -asingkatnya).
Stefan van den Akker
291

cat file2 >> file1

The >>Operator menambahkan output ke file bernama atau menciptakan file bernama jika tidak ada.

cat file1 file2 > file3

Ini menggabungkan dua atau lebih file menjadi satu. Anda dapat memiliki banyak file sumber yang Anda butuhkan. Sebagai contoh,

cat *.txt >> newfile.txt

Perbarui 20130902
Dalam komentar, eumiro menyarankan "jangan coba-coba cat file1 file2 > file1." Alasan ini mungkin tidak menghasilkan hasil yang diharapkan adalah bahwa file yang menerima pengalihan disiapkan sebelum perintah di sebelah kiri >dieksekusi. Dalam hal ini, pertama file1- tama dipotong menjadi nol panjang dan dibuka untuk keluaran, kemudian catperintah mencoba untuk menggabungkan file yang sekarang panjangnya nol dengan isi file2ke dalam file1. Hasilnya adalah bahwa konten asli file1hilang dan sebagai gantinya adalah salinan file2yang mungkin bukan yang diharapkan.

Pembaruan 20160919
Dalam komentar, penerima saran menyarankan untuk menautkan informasi / sumber dukungan. Untuk referensi otoritatif, saya mengarahkan pembaca yang baik ke halaman manual sh di linuxcommand.org yang menyatakan:

Sebelum perintah dijalankan, input dan outputnya dapat dialihkan menggunakan notasi khusus yang ditafsirkan oleh shell.

Meskipun hal itu memberi tahu pembaca apa yang perlu mereka ketahui, mudah untuk dilewatkan jika Anda tidak mencarinya dan menguraikan kata demi kata pernyataan. Kata yang paling penting di sini adalah 'sebelum'. Pengalihan selesai (atau gagal) sebelum perintah dijalankan.

Dalam contoh kasus cat file1 file2 > file1shell melakukan pengalihan terlebih dahulu sehingga I / O menangani berada di lingkungan di mana perintah akan dieksekusi sebelum dieksekusi.

Versi yang lebih ramah di mana pendahuluan pengalihan dibahas panjang lebar dapat ditemukan di situs web Ian Allen dalam bentuk courseware Linux. Halaman I / O Redirection Notes- nya banyak berbicara tentang topik tersebut, termasuk pengamatan bahwa pengalihan berfungsi bahkan tanpa perintah. Melewati ini ke shell:

$ >out

... membuat file kosong bernama keluar. Shell pertama-tama mengatur pengalihan I / O, kemudian mencari perintah, tidak menemukan, dan menyelesaikan operasi.

T.Rob
sumber
17
@ asir - jangan coba cat file1 file2 > file1- ini tidak akan berhasil seperti Anda mungkin sedang menunggu.
eumiro
5
Sebenarnya inilah yang dia butuhkan. Dia mengatakan "tanpa menimpa file saat ini1." Tiga penjawab pertama benar-benar mengabaikan bagian pertanyaan ini dan menyarankan perintah >>yang akan memodifikasi file file1. T.Rob melakukan pekerjaan yang jauh lebih unggul untuk menjelaskan jawabannya daripada hanya berlomba untuk mengirimkan sesuatu yang, pada kenyataannya, salah. Berdasarkan teks pertanyaan, saya percaya itu cat file1 file2 > file3adalah perintah yang tepat yang @asir cari.
dm78
Terima kasih atas kata-kata baiknya, David! Apa yang @eumiro tunjukkan di atas tetapi tidak merinci adalah bahwa operasi di sebelah kanan >dijalankan terlebih dahulu. Jadi mengeksekusi cat file1 file2 > file1pertama kali clobber file1kemudian mencoba untuk menyalin file sekarang-nol-panjang ke dirinya sendiri. Ini masuk akal ketika Anda memikirkan urutan operasi yang dapat dan harus terjadi tetapi cukup halus sehingga mengejutkan banyak orang. Jadi jika tidak ada yang lain, eumiro dan Anda telah mendorong peningkatan lebih lanjut untuk jawabannya. Terima kasih untuk itu!
T.Rob
Juga jangan coba cat file1 >> file1, ini akan menyebabkan file ditulis ulang secara rekursif, saya keliru melakukan ini dan hanya dalam beberapa detik, 50 juta baris telah dimasukkan ke dalam file dari sebelumnya hanya beberapa lusin baris.
Hendra Uzia
Juga, hanya untuk membuatnya lebih ringkas, jika "file baru" sudah ada, >> tambahkan ke file dan > ganti file.
rinogo
43

Catatan : jika Anda perlu menggunakan sudo , lakukan ini:

sudo bash -c 'cat file2 >> file1'

Metode yang biasa dengan hanya menambahkan sudopada perintah akan gagal, karena eskalasi privilege tidak terbawa ke redirection output.

jdunk
sumber
6
Ungkapan umum lain untuk ini adalahcat file2 | sudo tee -a file1 > /dev/null
ianw
28

Coba perintah ini:

cat file2 >> file1
eumiro
sumber
13

Hanya untuk referensi, menggunakan ddrescue menyediakan cara yang tidak terputus untuk mencapai tugas jika, misalnya, Anda memiliki file besar dan kebutuhan untuk berhenti sementara kemudian melanjutkan di beberapa titik kemudian:

ddrescue -o $(wc --bytes file1 | awk '{ print $1 }') file2 file1 logfile

Ini logfileadalah bagian yang penting. Anda dapat menginterupsi proses dengan Ctrl-Cdan melanjutkannya dengan menentukan perintah yang sama persis lagi dan ddrescue akan membaca logfiledan melanjutkan dari tempat sebelumnya. The -o Aflag mengatakan ddrescue mulai dari byte A dalam file output ( file1). Jadi wc --bytes file1 | awk '{ print $1 }'cukup ekstrak ukuran file1dalam byte (Anda bisa menempelkan output dari lsjika Anda mau).

Seperti yang ditunjukkan oleh ngks di komentar, downside adalah bahwa ddrescue mungkin tidak akan diinstal secara default, jadi Anda harus menginstalnya secara manual. Komplikasi lain adalah ada dua versi ddrescue yang mungkin ada di repositori Anda: lihat pertanyaan askubuntu ini untuk info lebih lanjut. Versi yang Anda inginkan adalah ddrescue GNU, dan pada sistem berbasis Debian adalah paket bernama gddrescue:

sudo apt install gddrescue

Untuk distro lain periksa sistem manajemen paket Anda untuk versi ddrescue versi GNU .

Zorawar
sumber
1
Untuk kepentingan pengguna baru: ddrescue adalah alat GNU, tetapi mungkin tidak ada di Linux, Mac atau sistem serupa-unix lainnya. ddrescue tampaknya tidak diperlukan oleh POSIX atau standar lainnya.
2

Solusi lain:

cat file1 | tee -a file2

tee memiliki manfaat yang dapat Anda tambahkan ke file sebanyak yang Anda suka, misalnya:

cat file1 | tee -a file2 file3 file3

akan menambahkan konten file1ke file2, file3dan file4.

Dari halaman manual:

-a, --append
       append to the given FILEs, do not overwrite
Stefan van den Akker
sumber
0

catbisa menjadi solusi mudah tetapi itu menjadi sangat lambat ketika kami melakukan concat file besar, find -printadalah untuk menyelamatkan Anda, meskipun Anda harus menggunakan cat sekali.

amey@xps ~/work/python/tmp $ ls -lhtr
total 969M
-rw-r--r-- 1 amey amey 485M May 24 23:54 bigFile2.txt
-rw-r--r-- 1 amey amey 485M May 24 23:55 bigFile1.txt

 amey@xps ~/work/python/tmp $ time cat bigFile1.txt bigFile2.txt >> out.txt

real    0m3.084s
user    0m0.012s
sys     0m2.308s


amey@xps ~/work/python/tmp $ time find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1

real    0m2.516s
user    0m0.028s
sys     0m2.204s
Amey Jadiye
sumber
Penghematan waktu yang Anda laporkan untuk perintah find / cat combo adalah karena Anda menentukan waktu hanya perintah find yang mencetak nama file. Cobalah mengatur waktu seluruh perintah seperti ini: time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1)dan perintah ini akan menghasilkan hasil yang mirip dengan perintah kucing saja.
JoshMc
0

Anda juga dapat melakukan ini tanpa cat, meskipun sejujurnya catlebih mudah dibaca:

>> file1 < file2

The >>menambahkan STDIN ke file1dan <kesedihan file2untuk STDIN .

Alok Singh
sumber
1
Itu tidak bekerja.
user202729
@ user202729 Anda benar, itu tidak bekerja di bash. Itu bekerja di zsh.
Alok Singh