「dd bs=1 skip=N」ではなく、指定されたオフセットからファイルを出力するにはどうすればよいですか?

「dd bs=1 skip=N」ではなく、指定されたオフセットからファイルを出力するにはどうすればよいですか?

dd if=somefile bs=1 skip=1337 count=313370001 バイトの読み取りと書き込みを使用せずに、 のようなことを効率的に行うにはどうすればよいでしょうか?

解決策は次のように予想されます:

  1. 簡単に言うと(簡単でない場合は、これを実行する Perl ワンライナーを書くことができます)
  2. 大きなオフセットと長さをサポートするため(dd のブロック サイズのハックは役に立ちません)

部分的な解決策 (十分に単純ではありません。長さで同じことを試すと、さらに複雑になります):

dd if=somefile bs=1000 skip=1 count=31337 | { dd bs=337 count=1 of=/dev/null; rest_of_pipeline; }
# 1337 div 1000 and 1337 mod 1000

答え1

これは実行できるはずです (gnu dd の場合):

dd if=somefile bs=4096 skip=1337 count=31337000 iflag=skip_bytes,count_bytes

seek=も使用している場合は、 も検討してくださいoflag=seek_bytes

からinfo dd

`count_bytes'
      Interpret the `count=' operand as a byte count, rather than a
      block count, which allows specifying a length that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`skip_bytes'
      Interpret the `skip=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`seek_bytes'
      Interpret the `seek=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `oflag'.

Ps: この質問は古く、これらのフラグは質問が最初に行われた後に実装されたようですが、私が行った関連する dd 検索の最初の Google 結果の 1 つであるため、新しい機能で更新するとよいと思いました。


注: この回答は、GNU ddほとんどのLinuxディストリビューションで使用されている、GNU coreutils パッケージこの機能は、coreutils リリース 8.16 (2012 年 3 月 26 日、元の質問に回答してから数か月後) で導入されました。

注意事項Macユーザー: MacOSはBSDベースのUNIXユーティリティを使用していますが(主にライセンス上の理由から)、UNIXユーティリティのGNUバージョンは一般的に開発が活発で、多くの機能を備えています。MacにGNU coreutilsをインストールするには、自家製: brew install coreutils.

答え2

1 つのプロセスを使用してすべての初期バイトを破棄し、2 番目のプロセスを使用して実際のバイトを読み取ります。例:

echo Hello, World\! | ( dd of=/dev/null bs=7 count=1 ; dd bs=5 count=1 )

2 番目はdd、効率的と思われる任意のブロック サイズで入力を読み取ることができます。このためには追加のプロセスを生成する必要があることに注意してください。OS によってはコストが発生しますが、ファイルを 1 バイトずつ読み取るよりもコストは小さくなります (非常に小さなファイルの場合は問題はありません)。

答え3

bs=1使用の代わりに、bs=4096またはそれ以上。

答え4

hexdump コマンドを試すことができます:

hexdump  -v <File Path> -c -n <No of bytes to read> -s <Start Offset>

内容だけを見たい場合:

#/usr/bin/hexdump -v -C mycorefile -n 100 -s 100
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 
00000074 00 00 00 00 01 00 00 00 05 00 00 00 00 10 03 00 |................| 
00000084 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 |......@.........| 
00000094 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 03 00 |................| 
000000a4 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 |................| 
000000b4 06 00 00 00 00 10 03 00 00 00 00 00 00 90 63 00 |..............c.| 
000000c4 00 00 00 00 |....| 
000000c8 #

関連情報