Ecco come puoi farlo:
i=$(((t=19876543212)-(h=12345678901)))
{ dd count=0 skip=1 bs="$h"
dd count="$((i/(b=64*1024)-1))" bs="$b"
dd count=1 bs="$((i%b))"
} <infile >outfile
Questo è tutto ciò che è veramente necessario - non richiede molto di più. In primo luogo dd count=0 skip=1 bs=$block_size1
, lseek()
oltre i normali file di input praticamente istantaneamente. Non vi è alcuna possibilità di perdere dati o qualsiasi altra falsità venga comunicata al riguardo, puoi semplicemente cercare direttamente la posizione di partenza desiderata. Poiché il descrittore di file è di proprietà della shell e gli utenti lo dd
stanno semplicemente ereditando, influenzeranno la sua posizione del cursore e quindi è sufficiente eseguirlo a passi. È davvero molto semplice - e non esiste uno strumento standard più adatto all'attività di dd
.
Che utilizza una dimensione di blocchi di 64k che è spesso l'ideale. Contrariamente alla credenza popolare, blocchi più grandi non rendono il dd
lavoro più veloce. D'altra parte, neanche i minuscoli buffer vanno bene. dd
deve sincronizzare il suo tempo nelle chiamate di sistema in modo che non debba attendere la copia e la disconnessione dei dati, ma anche che non debba attendere le chiamate di sistema. Quindi vuoi che ci voglia abbastanza tempo che il prossimo read()
non debba aspettare l'ultimo, ma non così tanto che stai bufferando in dimensioni maggiori di quanto sia necessario.
Quindi il primo dd
passa alla posizione iniziale. Ci vuole zero tempo. Potresti chiamare qualsiasi altro programma che ti è piaciuto a quel punto per leggere il suo stdin e inizierà a leggere direttamente all'offset di byte desiderato. Ne chiamo un altro dd
per leggere i ((interval / blocksize) -1)
blocchi di conteggio su stdout.
L'ultima cosa che è necessaria è copiare il modulo (se presente) dell'operazione di divisione precedente. E quello è quello.
Non crederci, a proposito, quando le persone dichiarano fatti sul loro viso senza prove. Sì, è possibile dd
fare una breve lettura (anche se tali cose non sono possibili quando si legge da un dispositivo a blocchi sano, quindi il nome) . Tali cose sono possibili solo se non si bufferizza correttamente un dd
flusso che viene letto da un dispositivo a blocchi. Per esempio:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
In entrambi i casi dd
copia tutti i dati. Nel primo caso è possibile (anche se improbabile cat
) che alcuni dei blocchi di output che dd
copiano siano bit uguali a "$ num" byte perché dd
è specificato solo per bufferizzare qualsiasi cosa quando il buffer è specificamente richiesto sul suo comando- linea. bs=
rappresenta un massimo blocco-size perché lo scopo di dd
è in tempo reale i / o.
Nel secondo esempio specifico esplicitamente l'output a blocchi e le dd
letture dei buffer fino a quando non è possibile effettuare scritture complete. Ciò non influisce sul fatto count=
che si basa su blocchi di input, ma per questo hai solo bisogno di un altro dd
. Eventuali informazioni errate fornite altrimenti devono essere ignorate.
bs=1M iflag=skip_bytes,count_bytes