hexdumpをxxdにフォーマットする方法をxxd -revertで使用できますか?

hexdumpをxxdにフォーマットする方法をxxd -revertで使用できますか?

スキャンのためにSDカードの生のコンテンツをファイルにダンプしたいと思います。ほとんどはゼロです。 ~から学ぶこのスーパーユーザーの答えpvandの進行状況を表示するために使用できます。到着予定時刻はすべて1時間30分です。odhexdump

# pv /dev/sdd | od -x --endian=big > sdd_file
... ... ... [>                                     ] ... ETA 1:34:42

そして

# pv /dev/sdd | hexdump -C > sdd_file
... ... ... [>                                     ] ... ETA 1:35:01

しかし、xxd11時間かかります。

# pv /dev/sdd | xxd -a -u > sdd_file
... ... ... [>                                     ] ... ETA 10:48:53

私は主に可能性xxdのためにそれを好む。-revertしかし、xxdディスクの処理に時間がかかります。ファイルを転送できるように、同じ形式でファイルをフォーマットhexdump(または作成)するにはどうすればよいですか?odxxd-revertedxxd

ベストアンサー1

何人かの人々は言う xxd -rまた、hexdump出力を入力として受け入れます。でもテストしてみたらそうではありませんでした。また、ファイルがバックアップとしても使用される場合は、より保証された(つまり元のものとまったく同じ)形式を使用することをお勧めします。

インスピレーションをありがとうこの回答フォーマットする方法を学びましたhexdump

コア要約 - ソリューション

pv /dev/sdd | hexdump -e '"%08.8_ax: "' -e '2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " "' -e '" " 16/1 "%_p" "\n"' > sdd_file

いくつかの修正を行いました。

ご注意ください。 - ディスクがほとんどゼロになっている場合、これらの方法は圧縮と同様に非常に小さいファイルを生成します。それ以外の場合、出力ファイルはディスクサイズの約4倍になります。ドライブに十分な空き容量があることに注意してください。

試験を受ける

ファイルの準備。

# echo '- - - - Create a really large file of zeroes - - - -'
# dd bs=1100000000 count=4 if=/dev/zero of=test
4+0 records in
4+0 records out
4400000000 bytes (4.4 GB, 4.1 GiB) copied, 8.71123 s, 505 MB/s

# echo '- - - - Overwrite it with some letters in the beginning (without \n) - - - -'
# echo -n "ABCD xyz" > letters
# dd if=letters of=test conv=notrunc

# echo '- - - - Append some letters in the end (with \n) - - - -'
# echo "ABCD xyz" >> test

何を出力しますかxxd -a -u

# pv test | xxd -a -u > test_xxd
4.10GiB 0:05:39 [12.3MiB/s] [====================================================>] 100%

# cat test_xxd
00000000: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
10642ac00: 4142 4344 2078 797A 0A                   ABCD xyz.

(マイソリューション)出力をシミュレートする方法hexdump ...

# pv test | hexdump -e '"%08.8_ax: "' -e '2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " "' -e '" " 16/1 "%_p" "\n"' > test_hexdump
4.10GiB 0:00:29 [ 144MiB/s] [====================================================>] 100%

# cat test_hexdump
00000000: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
10642ac00: 4142 4344 2078 797A 0A                   ABCD xyz.

それらを比較してください。

# diff -s test_xxd test_hexdump
Files test_xxd and test_hexdump are identical

説明する

型構文がよく書かれています。hexdump マニュアルページ

   A format string contains any number of format units, separated by
   whitespace. A format unit contains up to three items: an
   iteration count, a byte count, and a format.

   The iteration count is an optional positive integer, which
   defaults to one. Each format is applied iteration count times.

   The byte count is an optional positive integer. If specified it
   defines the number of bytes to be interpreted by each iteration
   of the format.

   If an iteration count and/or a byte count is specified, a single
   slash must be placed after the iteration count and/or before the
   byte count to disambiguate them. Any whitespace before or after
   the slash is ignored.

私の解決策は3つのフォーマット文字列で構成されており、すべての後ろに-eオプションがあります。

-e '"%08.8_ax: "'

マニュアルページに記載されているように、フォーマット単位はです{ { iteration_count:1 / } byte_count } format。この場合、繰り返し回数とバイト数の両方を省略する。_aフォーマットでオフセットバイトを印刷しますx%08.8これは8文字を必要とし、前に0が付くという意味です。 (実際に%08_ax動作します。)

-e '2/1 "%02X" " " ... ... ... ... ... '

2番目の書式文字列は、書式セルを2/1 "%02X" " "8回繰り返します。列は8つです。2/1これは、1バイトが2回消費されることを意味します。これにより、出力16進数がビッグエンディアン形式になります。 2バイトを消費して16進数に変換すると、右側のバイトが最上位バイト(#1)と見なされます。私たちの番号付けシステムと直感的な認識とは異なり、出力が変わって表示されます。

この形式は、大文字HE、文字幅、左パディング"%02X"で表示するという意味です。X20

" "実際、繰り返し回数とバイト数が省略された別の形式単位です。 2バイトごとにスペースを追加します。

その後、この書式セルセットを8回繰り返して8列を印刷します。

#1 -hexdumpデフォルトではCPUのバイト順序を使用します(引用する)、ここでx86 / x64 CPUは16ビットサイズの単語でリトルエンディアンバイトシーケンスを使用します。

-e '" " 16/1 "%_p" "\n"'

最後に、3番目のフォーマット文字列はスペースでのみ始まります" "。その後、フォーマット単位が続きます16/1 "%_p"。繰り返しますが、1一度に1バイトを消費して何度も繰り返します16。通常、基本的に行われる%_pように、基本文字セットから文字を出力します。書式文字列の3番目の書式単位は改行文字のみを出力します。hexdump -Cxxd\n

私たちに不利な状況があったとき

私たちが解決しなければならない2つのことがあります。

TL;DR - (1) 必要に応じて最後の行を再度追加します。 (2) 空白ではなく重複した行を再度追加します。

行をスキップするアルゴリズム間の違いを観察してください。

# xxd -a -u test
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000030: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00000070: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000080: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000090: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

# hexdump -C test
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000020  41 42 43 44 20 78 79 7a  00 00 00 00 00 00 00 00  |ABCD xyz........|
*
00000040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000070  41 42 43 44 20 78 79 7a  00 00 00 00 00 00 00 00  |ABCD xyz........|
*
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000000d0

xxd

  1. xxd 常に最後の行を印刷してください。最後の行は重複行の考慮事項には含まれません。
  2. ~のため3つ以上連続した行をスキップして空白の行を繰り返しますxxd
  3. 復元するxxdと、空白行にはアスタリスク(*)のみが復元されます。xxdアスタリスクは、空白ではなく重複行として扱われません。これはxxd、空でない行は当初スキップしないためです。
  4. 規則(2)でも、2つの連続した空白行がある場合、両方はxxdスキップされません。ただし、復元時xxdに空の行にのみ復元するには、疑問符を受け入れます。xxdとてもよく処理されました。(これは後で証明します。)

hexdump

  1. hexdump常に印刷一行デフォルト形式を使用するファイルのバイト数。そのため、hexdump最後の行が重複行の場合はスキップできます。
  2. ~のため複数連続した行をスキップして空白または空でない行を繰り返しますhexdump

私たちのソリューションのデモンストレーション。

# pv test | hexdump -e '"%08.8_ax: "' -e '2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " " 2/1 "%02X" " "' -e '" " 16/1 "%_p" "\n"' > output
 208 B 0:00:00 [1.00MiB/s] [==================================>] 100%
# cat output
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00000020: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
*
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00000070: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
*
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*  

2つの修正。

  1. 最後の行にアスタリスクがある場合は、最後の行をスキップしたことを意味しますhexdump。ファイル(またはディスク)サイズから16バイト(たとえば、0x10)を引いたバイトオフセットを計算する必要があります。最後の行をもう一度追加するか、アスタリスクを最後の行に置き換えます。
  2. アスタリスクの前の行が空白行でない場合は、空でないhexdump行をスキップすることを意味します。空でない重複行を再追加する必要があります。
  3. 最後の行を追加するときは、空白または空白以外の行が必要になることがあります。

ディスクサイズを見つけるにはlsblk -b

修理後。

# vi output
# cat output
00000000: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00000020: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000030: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
00000070: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000080: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
00000090: 4142 4344 2078 797A 0000 0000 0000 0000  ABCD xyz........
000000a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
*
000000c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................

回復して確認してください。

# xxd -r output restore

# diff -s test restore
Files test and restore are identical

ご注意ください。行00000010:と行で000000b0アスタリスクに置き換えられた単一の空行はうまく機能しますxxd -revert

おすすめ記事