Oto jak możesz to zrobić:
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
To wszystko, co jest naprawdę konieczne - nie wymaga wiele więcej. Po pierwsze dd count=0 skip=1 bs=$block_size1
, lseek()
nad regularnym wprowadzaniem plików praktycznie natychmiast. Nie ma szans na pominięcie danych lub jakiekolwiek inne nieprawdziwe informacje na ten temat, możesz po prostu szukać bezpośrednio do pożądanej pozycji początkowej. Ponieważ deskryptor pliku jest własnością powłoki, a pliki dd
po prostu dziedziczą ją, wpłyną one na jej pozycję kursora, więc możesz to zrobić krok po kroku. To naprawdę jest bardzo proste - i nie ma standardowego narzędzia, które lepiej odpowiadałoby temu zadaniu niż dd
.
Wykorzystuje rozmiar bloku 64k, co często jest idealne. W przeciwieństwie do powszechnego przekonania, większe rozmiary bloków nie przyspieszają dd
pracy. Z drugiej strony małe bufory też nie są dobre. dd
musi zsynchronizować swój czas w wywołaniach systemowych, aby nie musiał czekać na kopiowanie danych do pamięci i ponownie, ale także, aby nie musiał czekać na wywołania systemowe. Więc chcesz, aby zajęło to wystarczająco dużo czasu, aby następny read()
nie musiał czekać na ostatni, ale nie tak bardzo, że buforujesz w większych rozmiarach niż to konieczne.
Pierwszy dd
przeskakuje do pozycji początkowej. To zajmuje zero czasu. Możesz wywołać dowolny inny program, który lubisz w tym momencie, aby odczytać jego standardowe wejście, a program zacznie czytać bezpośrednio z wybranym przesunięciem bajtu. Dzwonię dd
do innego, żeby odczytać ((interval / blocksize) -1)
bloki liczników na standardowe wyjście.
Ostatnią rzeczą, która jest konieczna, jest skopiowanie modułu (jeśli istnieje) z poprzedniej operacji dzielenia. I to jest to.
Nawiasem mówiąc, nie wierz w to, kiedy ludzie przedstawiają fakty na twarzy bez dowodów. Tak, możliwe jest dd
wykonanie krótkiego odczytu (chociaż takie rzeczy nie są możliwe przy odczycie ze zdrowego urządzenia blokowego - stąd nazwa) . Takie rzeczy są możliwe tylko wtedy, gdy nie buforujesz poprawnie dd
strumienia odczytanego z urządzenia innego niż urządzenie blokowe. Na przykład:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
W obu przypadkach dd
skopiuj wszystkie dane. W pierwszym przypadku jest to możliwe (choć mało prawdopodobne, z cat
) , że niektóre z bloków wyjściowych, które dd
kopiuje OUT bit równy „$ num” Bajty ponieważ dd
jest spec''d tylko do bufora w ogóle nic, gdy bufor jest wyraźnie wymagane na jej Command linia. bs=
reprezentuje maksymalny rozmiar bloku, ponieważ celemdd
jest we / wy w czasie rzeczywistym.
W drugim przykładzie jawnie określam wyjściowy rozmiar bloku i dd
odczyty buforów, aż możliwe będzie pełne zapisanie . Nie ma to wpływu na count=
to, co jest oparte na blokach wejściowych, ale do tego potrzebujesz tylko innego dd
. Wszelkie dezinformacje podane w inny sposób powinny zostać zignorowane.
bs=1M iflag=skip_bytes,count_bytes