Non penso che tu possa farlo, non in modo affidabile e non nel modo in cui lo chiedi. Il fatto è che il rapporto di compressione dell'archivio probabilmente non sarà distribuito uniformemente dalla testa alla coda - l'algoritmo di compressione si applicherà meglio ad alcune parti rispetto ad altre. Funziona così. E quindi non puoi fattorizzare la tua divisione sulla dimensione del file compresso.
Inoltre, gzip
non supporta l'archiviazione delle dimensioni originali dei file compressi di dimensioni superiori a 4 GB - non può gestirlo. E quindi non puoi interrogare l'archivio per ottenere una dimensione affidabile, perché ti ingannerà.
La cosa a 4 righe - è abbastanza facile, davvero. La cosa da 4 file: non so come poterlo fare in modo affidabile e con una distribuzione uniforme senza prima estrarre l'archivio per ottenere le sue dimensioni non compresse. Non credo che tu possa perché ho provato.
Tuttavia, ciò che puoi fare è impostare una dimensione massima per i file di output divisi e assicurarti che siano sempre rotti alle barriere dei record. Che puoi fare facilmente. Ecco un piccolo script che lo farà estraendo l' gzip
archivio e eseguendo il piping del contenuto attraverso alcuni dd
pipe buffer specifici con count=$rpt
argomenti specifici , prima di passarlo attraverso lz4
per decomprimere / ricomprimere ogni file al volo. Ho anche lanciato alcuni tee
trucchetti per stampare anche le ultime quattro righe per ogni segmento su stderr.
( 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
)
Continuerà fino a quando non avrà gestito tutti gli input. Non tenta di dividerlo per una percentuale - che non può ottenere - ma invece lo divide per un conteggio di byte non elaborati massimo per divisione. E comunque, una grande parte del tuo problema è che non puoi ottenere una dimensione affidabile sul tuo archivio perché è troppo grande - qualunque cosa tu faccia, non farlo di nuovo - fai le divisioni a meno di 4 g un pezzo in questo giro , può essere. Questo piccolo script, almeno, ti consente di farlo senza dover mai scrivere un byte non compresso su disco.
Ecco una versione più breve ridotta all'essenziale: non aggiunge tutte le cose del rapporto:
( 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
Fa tutte le stesse cose della prima, per lo più, semplicemente non ha molto da dire al riguardo. Inoltre, c'è meno disordine, quindi è più facile vedere cosa sta succedendo, forse.
Il IFS=
punto è solo gestire una read
riga per iterazione. Noi read
uno perché abbiamo bisogno che il nostro ciclo termini alla fine dell'input. Questo dipende dalla dimensione del record , che, per il tuo esempio, è di 354 byte per. Ho creato un gzip
archivio da 4 + gb con alcuni dati casuali per testarlo.
I dati casuali sono stati ottenuti in questo modo:
( 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
... ma forse non devi preoccuparti così tanto, dato che hai già i dati e tutto il resto. Torna alla soluzione ...
Fondamentalmente pigz
- che sembra decomprimersi un po 'più velocemente di quanto non faccia zcat
- esegue il pipe out del flusso non compresso e dd
buffer che vengono emessi in blocchi di scrittura dimensionati specificamente con un multiplo di 354 byte. Il ciclo sarà read
una $line
volta ogni iterazione di test che ingresso è ancora arrivando, che sarà printf
poi printf
a lz4
prima di un altro dd
è chiamato a leggere blocchi di dimensioni specificamente ad un multiplo di 354 byte - di sincronizzarsi con il buffer dd
di processo - per la durata. Ci sarà una breve lettura per iterazione a causa dell'iniziale read $line
- ma non importa, perché lo stiamo stampando al lz4
nostro processo di raccolta - comunque.
L'ho impostato in modo che ogni iterazione legga circa 1 gb di dati non compressi e comprima tale in-stream a circa 650 Mb circa. lz4
è molto più veloce di qualsiasi altro metodo di compressione utile, motivo per cui l'ho scelto qui perché non mi piace aspettare. xz
farebbe comunque un lavoro molto migliore alla compressione effettiva, probabilmente. Una cosa a riguardo lz4
, tuttavia, è che spesso può decomprimere a velocità vicine alla RAM, il che significa molte volte che puoi decomprimere un lz4
archivio velocemente come potresti scriverlo in memoria comunque.
Quello grande fa alcuni rapporti per iterazione. Entrambi i loop stamperanno dd
il rapporto sul numero di byte grezzi trasferiti, sulla velocità e così via. Il grande ciclo stamperà anche le ultime 4 righe di input per ciclo, e un byte conta per lo stesso, seguito da una ls
delle directory in cui scrivo gli lz4
archivi. Ecco un paio di round di 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
?