如何合并两个 ddrescue 图像?

如何合并两个 ddrescue 图像?

我有两个 ddrescue 映像,是通过同一媒体的连续恢复尝试创建的。两个图像大小相同,但具有互补的数据:

$ od part-one/ddrescue_image --skip-bytes 227966006774 --read-bytes 32
3242365232766 113056 016517 102014 074371 144073 000000 000000 000000
3242365233006 000000 000000 000000 000000 000000 000000 000000 000000
3242365233026
$ od part-two/ddrescue_image --skip-bytes 227966006774 --read-bytes 32
3242365232766 000000 000000 000000 000000 000000 124616 163450 064251
3242365233006 074567 134433 012742 022160 044301 054235 140604 020633
3242365233026

如何将它们合并成一个完整的图像?

细节

  • 第二张图片只是第一次恢复尝试的延续,如下:

    $ ddrescue corrupt-partition part-one/ddrescue_image part-one/ddrescue_log
    $ mkdir part-two; cp part-one/ddrescue_log part-two/ddrescue_log
    $ ddrescue corrupt-partition part-two/ddrescue_image part-two/ddrescue_log
    
  • 第二个图像几乎完全为零,但包含分布在 1847 个隔离区域的 18 KB 恢复数据。

  • 我尝试使用提到的技术在此邮件列表中,

    $ ddrescue --domain-logfile=part-two/ddrescue_log part-two/ddrescue_image part-one/ddrescue_image part-one/ddrescue_log
    
    
    GNU ddrescue 1.16
    Press Ctrl-C to interrupt
    Initial status (read from logfile)
    rescued:   937286 MB,  errsize:   62976 B,  errors:     122
    Current status
    rescued:   937286 MB,  errsize:   62976 B,  current rate:        0 B/s
       ipos:         0 B,   errors:     122,    average rate:        0 B/s
       opos:         0 B,     time since last successful read:       0 s
    Finished
    

    但它似乎没有改变任何东西。

答案1

如果您确切知道要复制哪个数据区域,可以使用dd

dd conv=notrunc if=input of=output seek=123456 skip=123456 bs=4k count=128

这将从 123456 开始将 128 个 4k 块从输入复制到输出。

谨慎的做法是首先备份您要覆盖的块:

dd if=output skip=123456 bs=4k count=128 of=output-backup-bs4k-pos123456

如果您不知道要复制哪个数据区域或不确定,GNU dd碰巧知道sparse

dd conv=notrunc,sparse if=input of=output bs=4k

这会将每个非零 4k 输入块复制到输出。bs=512如果您的块较小,请使用!

请注意,此方法没有备份,因此如果该文件很重要,您最好复制该文件。

答案2

尝试这样的事情吗?

dd if=part-one/ddrescue_image bs=1 count=227966006784 >result
dd if=part-two/ddrescue_image bs=1 seek=227966006785 >>result

小块大小会使速度变得非常慢;如果您可以重构以使用更大的块大小并且仍然以正确的偏移量着陆,那么这应该会使其速度更快。

如果你做不到这一点,那么将操作拆分为更多的dd调用可能是一个好主意——使用大块大小(例如 65536)读取到最近的 64K 边界,然后从那里放慢速度(可能逐步降低到 1K 块)大小到最近的 1K 边界,然后一直到单个字节),然后在完成细粒度操作后再次加快速度。

相关内容