Menggabungkan File Dan Menyisipkan Baris Baru Di Antara File

127

Saya memiliki banyak file yang ingin saya gabungkan cat. Katakanlah

File1.txt 
foo

File2.txt
bar

File3.txt
qux

Saya ingin menyimpulkan sehingga file terakhir terlihat seperti:

foo

bar

qux

Bukan ini dengan biasanya cat File*.txt > finalfile.txt

foo
bar 
qux

Bagaimana cara yang benar untuk melakukannya?

neversaint
sumber

Jawaban:

121

Anda dapat melakukan:

for f in *.txt; do (cat "${f}"; echo) >> finalfile.txt; done

Pastikan file finalfile.txttidak ada sebelum Anda menjalankan perintah di atas.

Jika Anda diizinkan untuk menggunakan, awkAnda dapat melakukan:

awk 'FNR==1{print ""}1' *.txt > finalfile.txt
codaddict
sumber
10
AWK '{print $0}' *.txt
timger
7
Ini memiliki kekurangan yang berbeda bahwa akan ada baris kosong baik di akhir (dari alternatif pertama) atau di awal (alternatif kedua). Anda dapat dengan mudah mencegah ini dengan awk 'FNR==1 && NR > 1 ...'sebaliknya.
tripleee
5
Jika Anda meletakkan >finalfile.txtsetelah doneAnda dapat menimpa alih-alih menambahkan, yang akan menghapus persyaratan untuk memastikan file tersebut hilang atau kosong sebelum perulangan.
tripleee
53

Jika Anda memiliki cukup sedikit file yang dapat Anda daftarkan masing-masing, maka Anda dapat menggunakan substitusi proses di Bash, menyisipkan baris baru di antara setiap pasangan file:

cat File1.txt <(echo) File2.txt <(echo) File3.txt > finalfile.txt
Robert Tupelo-Schneck
sumber
1
Cantik! Terima kasih.
Bob Kocisko
Ini bekerja dengan baik bagi saya untuk sertifikat Letsencrypt saya untuk membuat file .pem.
leeman24
35

Jika saya melakukannya, saya akan menggunakan sed:

sed -e '$s/$/\n/' -s *.txt > finalfile.txt

Dalam pola sed ini $ memiliki dua arti, pertama cocok dengan nomor baris terakhir saja (sebagai rentang baris untuk menerapkan pola) dan kedua cocok dengan akhir baris dalam pola substitusi.

Jika versi sed Anda tidak memiliki -s(memproses file input secara terpisah), Anda dapat melakukan semuanya sebagai loop:

for f in *.txt ; do sed -e '$s/$/\n/' $f ; done > finalfile.txt
Flexo
sumber
3
Atau di GNU sed:sed -s '$G' *.txt > finalfile.txt
Ruud Helderman
Hanya satu aliran! ini harus menjadi jawaban yang diterima!
Yassine ElBadaoui
hati-hati teman-teman, saya baru saja merusak PC saya karena saya menggunakannya findsebagai pengganti *.txt, yang berarti file itu ditambahkan ke dirinya sendiri!
Xerus
11

Anda dapat melakukannya dengan menggunakan xargsjika Anda suka, tetapi ide utamanya masih sama:

find *.txt | xargs -I{} sh -c "cat {}; echo ''" > finalfile.txt
Nick Roz
sumber
1
Terima kasih. Saya merasa xargsjauh lebih mudah digunakan daripada loop di bash.
RawwrBag
9

Ini berfungsi di Bash:

for f in *.txt; do cat $f; echo; done

Berbeda dengan jawaban dengan >>(append), output dari perintah ini dapat disalurkan ke program lain.

Contoh:

  • for f in File*.txt; do cat $f; echo; done > finalfile.txt
  • (for ... done) > finalfile.txt (orang tua adalah opsional)
  • for ... done | less (menyalurkan lebih sedikit)
  • for ... done | head -n -1 (ini menghilangkan garis kosong yang tertinggal)
pengguna3780389
sumber
7

Begitulah cara saya melakukannya di OsX 10.10.3

for f in *.txt; do (cat $f; echo '') >> fullData.txt; done

karena perintah 'echo' sederhana tanpa parameter berakhir dengan tidak ada baris baru yang dimasukkan.

lbrutti
sumber
Ini menempatkan string di akhir file; bagaimana cara memasukkannya di antara setiap file?
onassar
3

Dalam python, ini digabungkan dengan baris kosong antar file ( ,menekan menambahkan baris kosong tambahan):

print '\n'.join(open(f).read() for f in filenames),

Ini adalah python one-liner jelek yang dapat dipanggil dari shell dan mencetak hasilnya ke file:

python -c "from sys import argv; print '\n'.join(open(f).read() for f in argv[1:])," File*.txt > finalfile.txt
pengguna3780389
sumber