Apa cara terbaik untuk menggabungkan file lagi setelah membaginya?

73

Jika saya memiliki file besar dan perlu membaginya menjadi 100 megabyte, saya akan melakukannya

split -b 100m myImage.iso

Itu biasanya memberi saya sesuatu seperti

xaa
xab
xac
xad

Dan untuk mengembalikan mereka, saya telah menggunakan

cat x* > myImage.iso

Sepertinya harus ada cara yang lebih efisien daripada membaca setiap baris kode dalam sekelompok file dengan catdan mengarahkan output ke file baru. Seperti cara hanya membuka dua file, menghapus EOFpenanda dari yang pertama, dan menghubungkannya - tanpa harus melalui semua konten.

Windows / DOS memiliki perintah salin untuk file biner. Bantuan menyebutkan bahwa perintah ini dirancang untuk dapat menggabungkan beberapa file. Ini bekerja dengan sintaks ini: ( /buntuk mode biner)

copy /b file1 + file2 + file3 outputfile

Apakah ada yang serupa atau cara yang lebih baik untuk bergabung dengan file besar di Linux daripada kucing?

Memperbarui

Tampaknya itu catsebenarnya cara yang benar dan cara terbaik untuk bergabung dengan file. Senang mengetahui saya telah menggunakan perintah yang benar selama ini :) Terima kasih semuanya atas tanggapan Anda.

cwd
sumber
22
Catatan: Lebih baik tidak digunakan cat x*, karena urutan file tergantung pada pengaturan lokal Anda. Lebih baik mulai mengetik cat x, daripada menekan Esc dan kemudian *- Anda akan melihat urutan file yang diperluas dan dapat mengatur ulang.
rozcietrzewiacz
16
Alih-alih cat x*Anda dapat mempertimbangkan ekspansi brace shell, cat xa{a..g}yang memperluas urutan yang ditentukan untuk cat xaa xab xac xad xaf xaf xag
Peter.O
3
@rozcietrzewiacz - dapatkah Anda memberikan contoh bagaimana saya akan menyesuaikan pengaturan lokal saya yang akan rusak cat x*? Apakah pengaturan lokal baru juga tidak mempengaruhi splitsehingga jika splitdan cat x*digunakan pada sistem yang sama mereka akan selalu berfungsi?
cwd
3
"Membuka dua file, menghapus penanda EOF dari yang pertama, dan menghubungkannya - tanpa harus melalui semua isinya." ... sepertinya Anda perlu menciptakan sistem file baru untuk melakukan apa yang Anda inginkan
JoelFan
6
@cwd: Melihat split.cdi GNU Coreutils, akhiran dibangun dari array tetap karakter: static char const *suffix_alphabet = "abcdefghijklmnopqrstuvwxyz";. Akhiran tidak akan terpengaruh oleh lokal. (Tapi saya tidak berpikir ada orang waras yang akan memesan ulang huruf kecil; bahkan EBCDIC mempertahankan pesanan standar mereka.)
Keith Thompson

Jawaban:

50

Untuk itulah catdibuat. Karena ini adalah salah satu alat GNU tertua, saya pikir sangat tidak mungkin bahwa alat lain melakukannya lebih cepat / lebih baik. Dan itu bukan pemipaan - itu hanya mengarahkan keluaran.

rozcietrzewiacz
sumber
The cat x, then press Esctrick yang Anda sebutkan adalah rapi .. saya sudah mencari sesuatu seperti itu, terima kasih ... komentar yang baik dan jawaban yang baik
Peter.O
2
Sama-sama :) :) Juga, ketika Anda memiliki daftar file pada baris perintah, Anda dapat menggunakan Ctrl+Wuntuk memotong kata dan kemudian Ctrl+Ymenempelkannya.
rozcietrzewiacz
kucing berarti "menyatukan"
JoelFan
4
.. dan "catenate" berasal dari kata Latin "catena" yang berarti "rantai" .. rangkai bergabung dengan tautan rantai. ... (dan sedikit lebih jauh dari topik, kurva catenary juga berasal dari "catena". Ini adalah cara rantai hang)
Peter.O
19

Dibawah tenda

Tidak ada cara yang lebih efisien selain menyalin file pertama, kemudian menyalin file kedua setelahnya, dan seterusnya. Baik DOS copydan catlakukan itu.

Setiap file disimpan secara terpisah dari file lain pada disk. Hampir setiap sistem file yang dirancang untuk menyimpan data pada perangkat seperti disk beroperasi dengan blok. Berikut adalah presentasi yang sangat disederhanakan tentang apa yang terjadi: disk dibagi menjadi beberapa blok, katakan 1 kB, dan untuk setiap file sistem operasi menyimpan daftar blok yang membuatnya. Sebagian besar file bukan jumlah blok bilangan bulat, jadi blok terakhir hanya ditempati sebagian. Dalam praktiknya, filesystem memiliki banyak optimisasi, seperti berbagi blok parsial terakhir antara beberapa file atau menyimpan "blok 46798 hingga 47913" daripada "blok 46798, blok 46799, ...". Ketika sistem operasi perlu membuat file baru, ia mencari blok gratis. Blok tidak harus berurutan: jika hanya blok 4, 5, 98 dan 178 yang gratis, Anda masih dapat menyimpan file 4kB.

Anda dapat mendukung blok parsial di file tengah, tetapi itu akan menambah kompleksitas, terutama ketika mengakses file secara tidak berurutan: untuk melompat ke byte ke-10340, Anda tidak bisa lagi melompat ke byte ke-100 dari blok ke-11, Anda harus untuk memeriksa panjang setiap blok intervensi.

Mengingat penggunaan blok, Anda tidak bisa hanya menggabungkan dua file, karena secara umum file pertama berakhir di pertengahan blok. Tentu, Anda dapat memiliki kasus khusus, tetapi hanya jika Anda ingin menghapus kedua file saat digabungkan. Itu akan menjadi penanganan yang sangat spesifik untuk operasi yang langka. Penanganan khusus seperti itu tidak hidup sendiri, karena pada sistem file tipikal, banyak file sedang diakses pada saat yang sama. Jadi, jika Anda ingin menambahkan pengoptimalan, Anda perlu berpikir hati-hati: apa yang terjadi jika beberapa proses lain membaca salah satu file yang terlibat? Apa yang terjadi jika seseorang mencoba menggabungkan A dan B ketika seseorang menggabungkan A dan C? Dan seterusnya. Secara keseluruhan, optimasi langka ini akan menjadi beban besar.

Secara keseluruhan, Anda tidak dapat membuat menggabungkan file lebih efisien tanpa membuat pengorbanan besar di tempat lain. Itu tidak layak.

Pada pemisahan dan bergabung

splitdan catmerupakan cara sederhana untuk memisahkan dan menggabungkan file. splitmengurus pembuatan file bernama dalam urutan abjad, sehingga cat *berfungsi untuk bergabung.

Kelemahan dari catbergabung adalah tidak kuat terhadap mode kegagalan umum. Jika salah satu file terpotong atau hilang, cattidak akan mengeluh, Anda hanya akan mendapatkan output yang rusak.

Ada utilitas kompresi yang menghasilkan arsip multi bagian, seperti zipsplitdan rar -v. Mereka tidak terlalu unixy, karena mereka kompres dan mengemas (merakit beberapa file menjadi satu) selain membelah (dan sebaliknya membongkar dan membuka kompres selain bergabung). Tetapi mereka berguna karena mereka memverifikasi bahwa Anda memiliki semua bagian, dan bahwa bagian-bagian itu selesai.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
8

Sepertinya harus ada cara yang lebih efisien daripada mem-pipkan semua konten melalui sistem stdin/stdout

Tapi bukan itu yang sebenarnya terjadi. Shell menghubungkan stdout cat langsung ke file yang terbuka, yang berarti bahwa "pergi melalui stdout" sama dengan menulis ke disk.

Ignacio Vazquez-Abrams
sumber
Saya hanya membayangkan menggunakan cat untuk menampilkan beberapa gigabyte kode di konsol, lalu memotretnya dan dimasukkan ke dalam file. Itulah citra mental yang saya miliki untuk apa yang harus terjadi ketika saya menggunakan cat dan mengarahkan output yang tidak bisa saya lihat. Sepertinya ada cara Anda bisa membuka dua file, menghubungkannya, dan kemudian menutupnya akan lebih efisien daripada menjalankan semua baris kode cat. Terima kasih telah memberi tahu saya tentang koneksi langsung.
cwd
@ cwd Anda dapat merancang sistem file di mana Anda dapat menggabungkan dua file dengan cara itu, tetapi itu akan sangat menyulitkan desain sistem file. Anda akan mengoptimalkan untuk satu operasi dengan biaya membuat banyak tugas umum lebih rumit dan lebih lambat.
Gilles 'SANGAT berhenti menjadi jahat'
@Gilles - akan menarik untuk mengetahui lebih banyak tentang detail tingkat rendah. Bagi saya, membaca semua sektor dari hard disk untuk beberapa file dan kemudian membuangnya kembali ke sektor lain yang tidak digunakan pada disk tampaknya tidak efisien. Dan saya pikir file besar harus disimpan di beberapa blok sektor bebas di kali karena mungkin tidak selalu ada blok yang berdampingan untuk menyimpannya. Karenanya secara teoritis Anda dapat menggabungkan file menjadi satu dengan menghapus penanda EOF dan menunjuk ke kelompok sektor pada awal file berikutnya. * nix sangat kuat jadi saya bertanya-tanya apakah ada cara yang lebih baik daripada kucing.
cwd
@cwd Tidak ada "penanda EOF". Tidak ada filesystem modern waras yang berfungsi seperti itu, karena mencegah beberapa karakter muncul dalam file (atau membutuhkan pengkodean yang kompleks). Tetapi bahkan jika ada penanda EOF, sebagian besar waktu, Anda tidak akan memiliki file yang tepat setelah itu.
Gilles 'SANGAT berhenti menjadi jahat'
Maksud saya konsep penanda EOF dan bukan penanda EOF yang sebenarnya. Kalau tidak, jika Anda melihat bit dan byte file pada hard drive, bagaimana Anda tahu di mana itu berakhir? Apakah Anda menentukan panjang file di awal? Saya berbicara tentang hal yang sangat rendah. Apakah itu yang Anda maksudkan juga?
cwd
3

Saya pernah memiliki masalah ini: saya ingin bergabung dengan beberapa file, tetapi tidak memiliki cukup ruang disk untuk menampungnya dua kali lipat.

Jadi saya menulis banyak program:

  • satu untuk "menyedot" file dengan membacanya, mengirimkannya ke stdout dan, jika sudah selesai, menghapusnya
  • dan satu untuk buffer data "on the fly".

Ini memungkinkan saya untuk melakukan sesuatu seperti

partto sourcefile | mybuffer 128M >>cumufile

dan dengan demikian menghapus file sumber sementara 128M masih tidak tertulis. Sedikit berbahaya, tetapi jika datanya tidak begitu berharga, atau mereka ada di tempat lain juga, itu layak.

Jika perlu, saya dapat menyediakan sumbernya.

glglgl
sumber
0

Secara teknis, ini adalah cara mengakses seluruh file tanpa harus membaca dan menulis seluruh konten, dan dapat berguna untuk file besar atau jika ada sedikit ruang tersisa:

$ mkfifo myImage.iso
$ cat xa{a..g} > myImage.iso &

Dan kemudian gunakan myImage.iso, misalnya

$ md5sum myImage.iso

Meskipun tentu saja myImage.isoadalah file khusus (bernama pipa) dan bukan file biasa, jadi ini mungkin berguna atau tidak tergantung pada apa yang Anda coba lakukan.

golimar
sumber
0

File Membelah

Dibagi Berdasarkan Ukuran

Jika Anda ingin membagi file besar menjadi file kecil dan pilih nama dan ukuran file output kecil ini adalah caranya.

split -b 500M videos\BigVideoFile.avi SmallFile.

Dengan cara ini Anda memilih untuk membagi satu file besar ke bagian yang lebih kecil dari 500 MB. Anda juga ingin nama file bagian adalah SmallFile. Perhatikan bahwa Anda perlu dot setelah nama file. Hasilnya harus menghasilkan file baru seperti ini:

SmallFile.ab SmallFile.ad SmallFile.af SmallFile.ah SmallFile.aj
SmallFile.aa SmallFile.ac SmallFile.ae SmallFile.ag SmallFile.ai SmallFile.ak
...

Dibagi Dengan Jumlah Garis

Dengan cara ini Anda akan membagi file tekstual menjadi file yang lebih kecil terbatas hingga 50 baris.

split -l 50 text_to_split.txt

Hasilnya harus seperti ini:

xaa xab xac ...

Pisahkan By Bytes

Dibagi menjadi file kecil dengan ukuran khusus file kecil dalam byte:

split -b 2048 BigFile.mp4

Hasilnya harus mirip dengan hasil dari Membagi Dengan Jumlah Garis .

File Bergabung

Anda dapat menggabungkan file dengan dua cara. Yang pertama adalah:

cat SmallFile.* > OutputBigVideoFile.avi

atau dengan:

cat SmallFile.?? > OutputBigVideoFile.avi

Catatan: Saat Anda bergabung file file file kecil tidak boleh rusak. Juga semua file kecil (bagian) harus dalam direktori yang sama.

Nole
sumber