web-dev-qa-db-ja.com

「dd bs = 1 skip = N」ではなく、指定されたオフセットからファイルを出力する方法

dd if=somefile bs=1 skip=1337 count=31337000のような方法で、効率的に、1バイトの読み取りと書き込みを使用しない方法は?

ソリューションは期待されています:

  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
30
Vi.

これはそれを行うべきです(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'.

追記:この質問は古く、これらのフラグは質問が最初に尋ねられた後に実装されたようですが、関連するdd検索の最初のGoogle結果の1つなので、新機能で更新します。

42
Fabiano

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

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

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

2
RolKau

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 #

の代わりに bs=1 使用する bs=4096 以上。

1
ccpizza