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


28

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

解決策が期待されます。

  1. シンプルにする(非シンプルな場合は、これを行うPerl onelinerを作成できます)
  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

ddが使用しているブロックサイズを変更しようとしていますか?
cmorse

ブロックサイズの変更=>スキップおよびカウントの単位の変更
Vi。

回答:


37

これはそれを行う必要があります(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つであるため、新しい特徴。


2

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

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

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


大きなオフセットとカウントに対してうまく動作しますか(つまり、メモリを大量に消費しないでください)。dd if=/dev/sda bs=10000000001 | dd bs=255 count=1 | hd-> "dd:無効な数値` 10000000001 '"
Vi。

@Vi。巨大なオフセットをスキップしたい場合は、一連の「理想的な」(ソースに応じて)サイズのブロック(16M)として最初の読み取りを実行し、メモリにある一連の小さいサイズのブロック(512)をドロップする必要があります、データを「ズーム」して、ブロックサイズに収まらない奇数のパーティション(bs = 1以下)を削除してから、必要なブロックを読み取ります。たとえば、オフセット10000000001から255バイトを読み取りたい: dd if=/dev/sda bs=16M skip=596 count=1 | dd bs=512 skip=1522 count=1 | (dd bs=1 count=1 of=/dev/null ; dd bs=255 count=1)
RolKau

確かread -nにスキップする方が使いやすいでしょうか?そして、head -cカウントする?たとえばcat somefile | (read -n 1337; head -c 31337000)、追加のプロセスを生成せずにそれを行うことができますexec 3<somefile; read -n 1337 -u 3; head -c 31337000 <&3
。– Gannet

1

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


2
次に、1337
Viの

1
なるほど、なるほど、おそらく、この例のように例えば、簡単なPythonスクリプトを書くことが容易になりますstackoverflow.com/questions/1035340/...f.seek(1337)使用する前にread(MY_CHUNK_SIZE)
ccpizza

最も信頼できる方法は、おそらくカスタム実行可能ファイルを作成することだと思われます。一部のシステムには、Python、Ruby、またはPerlさえありません。:|
トレイカズ

1

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 #

ファイルを16進数で表示することではありません。これは、指定されたバイト単位のオフセットからファイルの内容を抽出することです(たとえば、どこかにコピーするため)。
Vi。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.