Bunu şu şekilde yapabilirsiniz:
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
Gerçekten gerekli olan tek şey budur - daha fazlasını gerektirmez. İlk etapta hemen hemen düzenli dosya girişi üzerinde dd count=0 skip=1 bs=$block_size1olacak lseek(). Kaçırılan verilerin veya başka gerçek olmayan şeylerin söylendiği herhangi bir şans yoktur , doğrudan istediğiniz başlangıç pozisyonunu arayabilirsiniz. Dosya tanıtıcısı kabuğa ait olduğundan ve dd'leri yalnızca miras aldığından, imleç konumunu etkiler ve böylece adım adım atabilirsiniz. Gerçekten çok basit - ve göreve daha uygun standart bir araç yok dd.
Bu genellikle ideal olan 64k'lık bir blok boyutu kullanır. Popüler inanışın aksine, daha büyük blok boyutları ddişi daha hızlı yapmaz . Öte yandan, küçük tamponlar da iyi değil. ddverileri sistem çağrılarında senkronize etmelidir, böylece verileri belleğe ve tekrar dışarı kopyalamayı beklemek zorunda kalmaz, aynı zamanda sistem çağrılarını beklemesine gerek kalmaz. Bu yüzden bir sonrakinin read()sonda beklemek zorunda kalmayacağı kadar zaman almasını istiyorsunuz , ancak gerekenden daha büyük boyutlarda arabelleğe aldığınız kadar değil.
Böylece ilk ddbaşlangıç pozisyonuna atlar. Sıfır zaman alır . Bu noktada sevdiğiniz herhangi bir programı kendi stdin'ini okumak için çağırabilirsiniz ve doğrudan istediğiniz bayt ofsetinde okumaya başlayacaktır. Stdout'a sayım bloklarını ddokumak için başka birini arıyorum((interval / blocksize) -1)
Gerekli olan son şey , önceki bölüm işleminin modülünü (varsa) kopyalamaktır . Ve işte bu.
Bu arada, insanlar gerçekleri yüzlerinde kanıt olmadan ifade ettiklerinde inanmayın. Evet, ddkısa bir okuma yapmak mümkündür (ancak sağlıklı bir blok cihazdan - dolayısıyla adı okurken bu şeyler mümkün değildir) . Bu tür şeyler ancak ddbir blok cihazdan okunan bir akışı doğru şekilde arabelleğe almazsanız mümkündür . Örneğin:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
Her iki durumda da tüm verileri ddkopyalar . İlk durumda, kopyalanan çıkış bloklarının bir kısmının "$ num" baytına eşit olması olasıdır (ancak olası olmasa da ) , yalnızca komutta özel olarak istendiğinde herhangi bir şeyi arabelleğe alması gerekir. hat. Bir temsil maksimum çünkü blok boyutu amaçlı bir gerçek zamanlı I / O olduğu.catddddbs=dd
İkinci örnekte, çıktı blok boyutunu açıkça ddbelirtiyorum ve tam yazma işlemleri gerçekleştirilinceye kadar tamponları okuyor. Bu, count=giriş bloklarına dayalı olanı etkilemez , ancak bunun için başka bir taneye ihtiyacınız vardır dd. Size başka şekilde verilen yanlış bilgiler göz ardı edilmelidir.
bs=1M iflag=skip_bytes,count_bytes