Ini adalah bagaimana Anda melakukannya, Anda bisa melakukan ini:
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
Itu semua yang benar-benar diperlukan - tidak memerlukan lebih banyak Di tempat pertama dd count=0 skip=1 bs=$block_size1
akan lseek()
lebih dari input file biasa praktis instan. Tidak ada peluang data yang terlewat atau apa pun yang tidak benar lainnya diberitahu tentang hal itu, Anda bisa mencari langsung ke posisi awal yang Anda inginkan. Karena deskriptor file dimiliki oleh shell dan dd
itu hanya mewarisinya, mereka akan mempengaruhi posisi kursornya dan jadi Anda bisa mengambilnya dalam langkah-langkah. Ini sangat sederhana - dan tidak ada alat standar yang lebih cocok untuk tugas itu dd
.
Itu menggunakan 64k blocksize yang sering ideal. Berlawanan dengan kepercayaan populer, pemblokiran yang lebih besar tidak membuat dd
pekerjaan lebih cepat. Di sisi lain, buffer kecil juga tidak bagus. dd
perlu menyinkronkan waktunya dalam panggilan sistem sehingga tidak perlu menunggu menyalin data ke dalam memori dan keluar lagi, tetapi juga agar tidak perlu menunggu panggilan sistem. Jadi, Anda ingin mengambil waktu yang cukup berikutnyaread()
tidak harus menunggu pada yang terakhir, tetapi tidak terlalu banyak sehingga Anda buffering dalam ukuran yang lebih besar daripada yang diperlukan.
Jadi yang pertama dd
lompat ke posisi awal. Itu membutuhkan nol waktu. Anda dapat memanggil program lain yang Anda suka pada saat itu untuk membaca stdin-nya dan akan mulai membaca langsung di byte byte yang Anda inginkan. Saya memanggil orang lain dd
untuk membaca((interval / blocksize) -1)
blok hitungan ke stdout.
Hal terakhir yang diperlukan adalah menyalin modulus (jika ada) dari operasi divisi sebelumnya. Dan itu saja.
Omong-omong, jangan percaya ketika orang menyatakan fakta di wajah mereka tanpa bukti. Ya, dimungkinkan untuk dd
melakukan pembacaan singkat (meskipun hal-hal seperti itu tidak mungkin ketika membaca dari perangkat blok yang sehat - demikian namanya) . Hal-hal seperti itu hanya mungkin jika Anda tidak benar buffer dd
aliran yang dibaca dari selain perangkat blok. Sebagai contoh:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
Dalam kedua kasus dd
menyalin semua data. Dalam kasus pertama adalah mungkin (meskipun tidak mungkin dengan cat
) beberapa blok keluaran yangdd
menyalin akan menggigit sama dengan "$ num" byte karena dd
ditentukan hanya untuk buffer apa saja ketika buffer secara khusus diminta pada perintahnya- baris. bs=
merupakan maksimum blok-ukuran karena tujuan dari dd
adalah real-time i / o.
Dalam contoh kedua saya secara eksplisit menentukan keluaran blocksize dan dd
buffer membaca hingga penulisan lengkap dapat dilakukan. Itu tidak mempengaruhi count=
yang didasarkan pada blok input, tetapi untuk itu Anda hanya perlu yang lain dd
. Setiap informasi yang salah yang diberikan kepada Anda sebaliknya harus diabaikan.
bs=1M iflag=skip_bytes,count_bytes