合并大量重叠文件

合并大量重叠文件

我正在尝试从崩溃的磁盘中恢复 (MySQL) 数据库。有许多最近的转储,它们是损坏的 bz2 文件。由于数据库不经常更改,因此转储应该几乎相同。bzip2recover从文件中恢复了大约 70-80% 的块,因此可以通过查找文件中的重叠部分并将它们连接在一起来恢复大部分(如果不是全部)数据。例如:

dump1: |-----------------|xxxxxxxxxxxxxxxx|------------------|
dump2: |-------------|----------------|xxxxxxxxxxxxxxxxxxxxxx|
dump3: |xxxxxxxxxxxxxxxxxxxxxx|---------------|xxxxxxxxxxxxxx|

在这里,我可以检测到 dump1 中的第一个块是 dump2 中的第二个块的延续,而 dump2 中的第二个块是 dump3 中的第二个块的延续,而 dump3 中的第三个块是 dump1 中的第三个块的延续。通过合并这四个文件,我恢复了数据。

问题是有数千个文件(我有 10 个转储,每个转储约 400 个 1M 块)。是否有工具可以自动执行此过程,或至少自动执行部分过程(例如,使用 Linux 命令检查一个文件的结尾和另一个文件的开头之间的最长重叠)?

答案1

我需要这个完全相同的东西。我想出了这个出奇快的 Python 代码(它在 30 秒内将两个 2GB 的文件合并在一起,重叠部分为 800MB。)根据需要调整块的重叠大小。它应该尽可能长,但较少的比实际重叠尺寸。

#!/usr/bin/env python

import sys

overlap_size = 100000000 # 100MB

a = file(sys.argv[1]).read()
b = file(sys.argv[2]).read()
end = a[-overlap_size:]
offset = b.find(end)

c = file(sys.argv[3], 'wb')
c.write(a[:-overlap_size])
c.write(b[offset:])
c.close()

用法:

./join.py chunkA chunkB outputAB
./join.py outputAB chunkC outputABC
./join.py outputABC chunkD outputABCD
...etc

答案2

我没有可以帮你完成这项工作的工具,但你可以使用以下工具:

cmp -l dump1 dump2

这将为您提供不同字节及其偏移量的列表。重叠部分是 未打印偏移量的地方cmp

另外,您可以使用dd命令复制转储的一部分并将其附加到另一个转储。

您可以尝试编写使用这些工具的自己的脚本,或者编写一个小型 C 程序来比较这些文件并复制所需的部分。

我希望你发现这些想法很有用。

答案3

就像一个 Linux 命令检查一个文件的结尾和另一个文件的开头之间最长的重叠

传统上,这将是diff。它将生成两个给定文本文件的“差异”作为输出,以及一些控制信息(添加了什么、删除了什么、要检查哪些行)。patch命令能够逆转该过程。

理论上,您应该能够diff在不同的块上使用,对其输出进行一些处理(例如删除行删除的命令)并将其提供给patch

# echo 'this
> is
> a' > file1
# echo 'a
> chunked' > file2
# echo 'chunked
> data
> file' > file3

# diff file2 file1 | egrep -v '^>' | patch -p0 -R file1 -o file12
patching file file1

# cat file12
this
is
a
chunked

# diff file3 file12 | egrep -v '^>' | patch -p0 -R file12 -o -
patching file file12
this
is
a
chunked
data
file
#

请注意,如果您的输入文件非常大,diff则将需要大量内存。

答案4

我认为你必须自己编写这样一个工具。

从最大的文件开始,并将其作为图像复制到内存中。

然后逐个浏览所有文件,查找与当前内存映像的第一个或最后一个块重叠的部分。如果找到重叠部分,则扩展内存映像。

重复此操作,直到遍历所有文件而不添加任何字节。然后将内存映像写入文件。

相关内容