我希望将SD卡的原始内容转储到文件中以供检查。它的大部分是零。从这个超级用户的答案学习,我可以用pv来展示od和hexdump的进展。这两个时间都是1.5小时。
# pv /dev/sdd | od -x --endian=big > sdd_file
... ... ... [> ] ... ETA 1:34:42和
# pv /dev/sdd | hexdump -C > sdd_file
... ... ... [> ] ... ETA 1:35:01然而,xxd需要11个小时。
# pv /dev/sdd | xxd -a -u > sdd_file
... ... ... [> ] ... ETA 10:48:53我更喜欢xxd,主要是因为-revert的可能性。但是xxd处理磁盘所需的时间太长了。如何格式化hexdump (或od)以生成与xxd相同的文件格式,从而使该文件能够通过xxd成为-reverted?
发布于 2021-12-18 18:59:48
有人说 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" >> testxxd -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.我的解决方案包含三个格式字符串,后面都是-e选项。
-e '"%08.8_ax: "'正如手册页所提到的,格式单元是{ { iteration_count:1 / } byte_count } format。在这种情况下,迭代计数和字节计数都被省略了。_a以hex格式打印偏移字节。%08.8意味着它占据了8个字符,并在前面加了0。(事实上,只有%08_ax才能做到。)
-e '2/1 "%02X" " " ... ... ... ... ... '第二个格式字符串是格式单元2/1 "%02X" " "重复8次;有8列。2/1意味着消耗1字节2次。这确保输出十六进制为大端字节格式。如果我们消耗2个字节并将其转换为十六进制,右边的字节将被视为最重要的字节(#1)。输出将出现交换,与我们的编号系统,以及我们的直觉感知。
"%02X"格式意味着将其显示为大写字母HE,X在2字符宽度处显示,左填充0。
实际上," "是另一个具有省略迭代计数和字节计数的格式单元。它在每两个字节之间增加一个空格。
然后这组格式单元重复8次,打印8列。
#1 - hexdump默认使用CPU的endianness (参考),x86 / x64 CPU使用16位大小字的小endian。
-e '" " 16/1 "%_p" "\n"'最后,第三个格式字符串简单地以空格" "开头。然后是16/1 "%_p"的一个格式单元。同样,它一次消耗1字节,并迭代16次。%_p输出默认字符集中的字符,默认情况下hexdump -C和xxd通常会这样做。这个格式字符串\n的第三个格式单元只输出一个新的行字符。
当机会不在我们的利益时,
有两件事我们需要解决。
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 |................|
*
000000d0xxd
xxd总是打印最后一行。最后一行在重复行的考虑中被排除在外。xxd跳过连续行。xxd只将星号(*)恢复为空行。xxd不会将星号视为重复的非空行。这是因为xxd一开始不会跳过非空行。xxd也不会跳过其中的任何一行。但是,在还原时,xxd接受一个askerisk,仅将其还原为一个空行。xxd很好地处理了这个问题。(我们稍后将证明这一点。)hexdump
hexdump总是为文件字节计数多打印一行。这就是为什么如果是重复行,hexdump可以跳过最后一行的原因。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 ................
* 两次修复。
hexdump跳过。我们必须计算字节偏移量,即文件(或磁盘)大小减去16字节(即0x10)。或者向后添加最后一行,或者用最后一行替换星号。hexdump跳过了非空行。我们必须把这些非空的重复行加回去。要找到磁盘大小,我们可以使用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很好地处理。
https://unix.stackexchange.com/questions/683013
复制相似问题