Đây là cách bạn làm bạn có thể làm điều này:
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
Đó là tất cả những gì thực sự cần thiết - nó không đòi hỏi nhiều hơn nữa. Ở vị trí đầu tiên dd count=0 skip=1 bs=$block_size1
sẽ lseek()
trên đầu vào tập tin thường xuyên thực tế ngay lập tức. Không có cơ hội bỏ lỡ dữ liệu hoặc bất kỳ thông tin sai sự thật nào khác được nói về nó, bạn chỉ có thể tìm kiếm trực tiếp đến vị trí bắt đầu mong muốn của bạn. Bởi vì bộ mô tả tệp được sở hữu bởi trình bao và dd
chúng chỉ đơn thuần là kế thừa nó, nên chúng sẽ ảnh hưởng đến vị trí con trỏ của nó và vì vậy bạn chỉ cần thực hiện theo các bước. Nó thực sự rất đơn giản - và không có công cụ tiêu chuẩn nào phù hợp với nhiệm vụ hơn dd
.
Điều đó sử dụng kích thước khối 64k thường là lý tưởng. Trái với niềm tin phổ biến, các khối lớn hơn không làm cho dd
công việc nhanh hơn. Mặt khác, bộ đệm nhỏ cũng không tốt. dd
cần đồng bộ hóa thời gian của nó trong các cuộc gọi hệ thống để nó không cần phải chờ sao chép dữ liệu vào bộ nhớ và ra ngoài, mà còn để nó không phải chờ trong các cuộc gọi hệ thống. Vì vậy, bạn muốn nó mất đủ thời gian để người tiếp theo read()
không phải đợi đến lần cuối, nhưng không quá nhiều đến mức bạn phải đệm ở kích thước lớn hơn mức cần thiết.
Vì vậy, dd
bỏ qua đầu tiên đến vị trí bắt đầu. Điều đó không có thời gian. Bạn có thể gọi bất kỳ chương trình nào khác mà bạn thích vào thời điểm đó để đọc stdin của nó và nó sẽ bắt đầu đọc trực tiếp ở phần bù byte mong muốn của bạn. Tôi gọi một số khác dd
để đọc ((interval / blocksize) -1)
các khối đếm đến thiết bị xuất chuẩn.
Điều cuối cùng cần thiết là sao chép mô-đun (nếu có) của hoạt động phân chia trước đó. Và đó là điều đó.
Nhân tiện, đừng tin điều đó, khi mọi người nói lên sự thật trên khuôn mặt của họ mà không có bằng chứng. Có, có thể dd
thực hiện một lần đọc ngắn (mặc dù những điều như vậy là không thể khi đọc từ một thiết bị khối lành mạnh - do đó là tên) . Những điều như vậy chỉ có thể nếu bạn không đệm chính xác một dd
luồng được đọc từ ngoài một thiết bị khối. Ví dụ:
cat data | dd bs="$num" ### incorrect
cat data | dd ibs="$PIPE_MAX" obs="$buf_size" ### correct
Trong cả hai trường hợp dd
sao chép tất cả các dữ liệu. Trong trường hợp đầu tiên, có thể (mặc dù không chắc cat
) với một số khối đầu ra được dd
sao chép sẽ bit bằng "$ num" byte bởi vì dd
nó chỉ để đệm bất cứ thứ gì khi bộ đệm được yêu cầu cụ thể trên lệnh của nó- hàng. bs=
đại diện cho kích thước khối tối đa vì mục đích của dd
i / o thời gian thực.
Trong ví dụ thứ hai, tôi chỉ định rõ ràng khối đầu ra và dd
bộ đệm đọc cho đến khi hoàn thành ghi. Điều đó không ảnh hưởng đến count=
việc dựa trên các khối đầu vào, nhưng bạn chỉ cần một khối khác dd
. Bất kỳ thông tin sai lệch nào được cung cấp cho bạn nếu không nên được coi thường.
bs=1M iflag=skip_bytes,count_bytes