Saya tidak berpikir Anda bisa melakukan ini - tidak andal, dan bukan cara Anda bertanya. Masalahnya, rasio kompresi arsip mungkin tidak akan didistribusikan secara merata dari kepala ke ekor - algoritma kompresi akan berlaku lebih baik untuk beberapa bagian daripada yang lain. Begitulah cara kerjanya. Jadi Anda tidak dapat memfaktorkan pemisahan Anda pada ukuran file terkompresi.
Terlebih lagi, gzip
tidak mendukung penyimpanan ukuran asli file terkompresi yang berukuran lebih dari 4gb - tidak dapat menanganinya. Jadi Anda tidak dapat meminta arsip untuk mendapatkan ukuran yang andal - karena itu akan menipu Anda.
Masalah 4 baris - itu cukup mudah, sungguh. Masalah 4-file - Saya hanya tidak tahu bagaimana Anda bisa melakukannya dengan andal dan dengan distribusi yang merata tanpa terlebih dahulu mengekstraksi arsip untuk mendapatkan ukurannya yang tidak terkompresi. Saya tidak berpikir Anda bisa karena saya sudah mencoba.
Namun, apa yang dapat Anda lakukan, adalah mengatur ukuran maksimum untuk file output split, dan pastikan mereka selalu rusak pada batasan rekor. Itu bisa Anda lakukan dengan mudah. Berikut ini adalah skrip kecil yang akan melakukannya dengan mengekstraksi gzip
arsip, dan menyaring konten melalui beberapa dd
penyangga pipa eksplisit dengan count=$rpt
argumen tertentu , sebelum meneruskannya lz4
untuk mendekompresi / mengkompres ulang setiap file dengan cepat. Saya juga melemparkan beberapa tee
trik pipa kecil untuk mencetak empat baris terakhir untuk setiap segmen ke stderr juga.
( IFS= n= c=$(((m=(k=1024)*k)/354))
b=bs=354xk bs=bs=64k
pigz -d </tmp/gz | dd i$bs o$b |
while read -r line _$((n+=1))
do printf \\n/tmp/lz4.$n\\n
{ { printf %s\\n "$line"
dd count=$c i$b o$bs
}| tee /dev/fd/3|lz4 -BD -9 >/tmp/lz4.$n
} 3>&1| tail -n4 |tee /dev/fd/2 |
wc -c;ls -lh /tmp/[gl]z*
done
)
Itu hanya akan terus berjalan sampai semua input ditangani. Itu tidak mencoba untuk membaginya dengan beberapa persentase - yang tidak bisa didapat - tetapi sebaliknya membaginya per jumlah byte mentah maksimum per split. Dan lagi pula, sebagian besar masalah Anda adalah bahwa Anda tidak bisa mendapatkan ukuran yang dapat diandalkan pada arsip Anda karena terlalu besar - apa pun yang Anda lakukan, jangan lakukan itu lagi - buat perpecahan kurang dari 4gb sepotong ini berputar , mungkin. Skrip kecil ini, setidaknya, memungkinkan Anda untuk melakukan ini tanpa harus menulis byte yang tidak dikompresi ke disk.
Berikut ini adalah versi yang lebih pendek yang dilucuti untuk hal yang penting - ini tidak menambahkan semua hal laporan:
( IFS= n= c=$((1024*1024/354))
pigz -d | dd ibs=64k obs=354xk |
while read -r line _$((n+=1))
do { printf %s\\n "$line"
dd count=$c obs=64k ibs=354xk
} | lz4 -BD -9 >/tmp/lz4.$n
done
) </tmp/gz
Itu melakukan semua hal yang sama seperti yang pertama, kebanyakan, hanya saja tidak banyak bicara tentang itu. Juga, ada lebih sedikit kekacauan sehingga lebih mudah untuk melihat apa yang terjadi, mungkin.
The IFS=
hal yang hanya menangani satu read
baris per iterasi. Kami read
satu karena kami membutuhkan loop kami untuk mengakhiri ketika input berakhir. Ini tergantung pada ukuran rekaman Anda - yang, per contoh Anda, adalah 354 byte per. Saya membuat gzip
arsip 4+ gb dengan beberapa data acak untuk mengujinya.
Data acak didapat seperti ini:
( mkfifo /tmp/q; q="$(echo '[1+dPd126!<c]sc33lcx'|dc)"
(tr '\0-\33\177-\377' "$q$q"|fold -b144 >/tmp/q)&
tr '\0-\377' '[A*60][C*60][G*60][N*16][T*]' | fold -b144 |
sed 'h;s/^\(.\{50\}\)\(.\{8\}\)/@N\1+\2\n/;P;s/.*/+/;H;x'|
paste "-d\n" - - - /tmp/q| dd bs=4k count=kx2k | gzip
) </dev/urandom >/tmp/gz 2>/dev/null
... tapi mungkin Anda tidak perlu terlalu khawatir tentang itu, karena Anda sudah memiliki data dan semuanya. Kembali ke solusinya ...
Pada dasarnya pigz
- yang tampaknya melakukan dekompresi sedikit lebih cepat daripada yang dilakukan zcat
- menyalurkan aliran yang tidak terkompresi, dan dd
buffer yang menghasilkan blok-blok tulis yang berukuran khusus pada kelipatan 354-byte. Loop akan read
menjadi $line
sekali setiap iterasi untuk menguji bahwa masukan masih tiba, yang akan printf
kemudian printf
di lz4
sebelum lain dd
dipanggil untuk membaca blok berukuran khusus di kelipatan dari 354-byte - untuk sinkronisasi dengan penyangga dd
proses - untuk durasi. Akan ada satu bacaan pendek per iterasi karena inisial read $line
- tapi itu tidak masalah, karena kami mencetaknya di lz4
- proses kolektor kami -.
Saya telah mengaturnya sehingga setiap iterasi akan membaca sekitar 1gb data yang tidak terkompresi dan kompres sela itu menjadi sekitar 650MB. lz4
jauh lebih cepat daripada hampir semua metode kompresi berguna lainnya - itulah alasan saya memilihnya di sini karena saya tidak suka menunggu. xz
akan melakukan pekerjaan yang jauh lebih baik di kompresi yang sebenarnya, mungkin. Namun, satu hal yang lz4
sering terjadi adalah dekompres pada kecepatan mendekati RAM - yang berarti banyak kali Anda dapat mendekompres lz4
arsip dengan cepat karena Anda tetap dapat menuliskannya ke dalam memori.
Yang besar melakukan beberapa laporan per iterasi. Kedua loop akan mencetak dd
laporan tentang jumlah byte mentah yang ditransfer dan kecepatan dan sebagainya. Loop besar juga akan mencetak 4 baris input terakhir per siklus, dan jumlah byte untuk yang sama, diikuti oleh ls
direktori yang saya tulis lz4
arsipnya. Berikut adalah beberapa putaran output:
/tmp/lz4.1
2961+1 records in
16383+1 records out
1073713090 bytes (1.1 GB) copied, 169.838 s, 6.3 MB/s
@NTACGTANTTCATTGGNATGACGCGCGTTTATGNGAGGGCGTCCGGAANGC+TCTCTNCC
TACGTANTTCATTGGNATGACGCGCGTTTATGNGAGGGCGTCCGGAANGCTCTCTNCCGAGCTCAGTATGTTNNAAGTCCTGANGNGTNGCGCCTACCCGACCACAACCTCTACTCGGTTCCGCATGCATGCAACACATCGTCA
+
I`AgZgW*,`Gw=KKOU:W5dE1m=-"9W@[AG8;<P7P6,qxE!7P4##,Q@c7<nLmK_u+IL4Kz.Rl*+w^A5xHK?m_JBBhqaLK_,o;p,;QeEjb|">Spg`MO6M'wod?z9m.yLgj4kvR~+0:.X#(Bf
354
-rw-r--r-- 1 mikeserv mikeserv 4.7G Jun 16 08:58 /tmp/gz
-rw-r--r-- 1 mikeserv mikeserv 652M Jun 16 12:32 /tmp/lz4.1
/tmp/lz4.2
2961+1 records in
16383+1 records out
1073713090 bytes (1.1 GB) copied, 169.38 s, 6.3 MB/s
@NTTGTTGCCCTAACCANTCCTTGGGAACGCAATGGTGTGANCTGCCGGGAC+CTTTTGCT
TTGTTGCCCTAACCANTCCTTGGGAACGCAATGGTGTGANCTGCCGGGACCTTTTGCTGCCCTGGTACTTTTGTCTGACTGGGGGTGCCACTTGCAGNAGTAAAAGCNAGCTGGTTCAACNAATAAGGACNANTTNCACTGAAC
+
>G-{N~Q5Z5QwV??I^~?rT+S0$7Pw2y9MV^BBTBK%HK87(fz)HU/0^%JGk<<1--7+r3e%X6{c#w@aA6Q^DrdVI0^8+m92vc>RKgnUnMDcU:j!x6u^g<Go?p(HKG@$4"T8BWZ<z.Xi
354
-rw-r--r-- 1 mikeserv mikeserv 4.7G Jun 16 08:58 /tmp/gz
-rw-r--r-- 1 mikeserv mikeserv 652M Jun 16 12:32 /tmp/lz4.1
-rw-r--r-- 1 mikeserv mikeserv 652M Jun 16 12:35 /tmp/lz4.2
zcat file > /dev/null
waktu?