Слияние ненулевых отличающихся байтов в больших файлах

Я пробую к спасению старый поцарапанный DVD путем разрыва его к ISO. Я имею двух читателей и создал ISO от каждого. Каждый читатель не может считать определенные различные байты DVD и заменяет их 0s. Когда я сравниваю использование файлов cmp -l file1.iso file2.iso, Я вижу, что определенные байты слева 0, в то время как определенные другие байты справа 0 (соответствующие байты на других файлах являются ненулевыми). Я хочу создать 3-й файл, сказать file3.iso это объединяет ненулевые отличающиеся байты из вышеупомянутых двух файлов. Как пример, предположите для простоты, что каждый файл имеет 6 байтов следующим образом

file1.iso   file2.iso
---------   ---------
0           0
1           1
2           0
3           0
0           4
0           5

file3.iso должен быть следующие:

0
1
2
3
4
5

Файлы являются довольно большими (приблизительно 8 ГБ). Каждый файл имеет то же число байтов. Я использую Ubuntu 16.04

Может любой предлагать самый легкий способ сделать то, что я хочу. Я могу использовать вывод cmp -l как промежуточные данные, но хотят избежать написания кода.

3
задан 24 March 2019 в 11:47

1 ответ

Я записал сценарий Python для Вас.

#!/usr/bin/env python3
'''
Given two input files and one output file, merge the input files on
matching bytes or bytes that are null in one file but not the other.
Non-matching non-null bytes will raise a ValueError.
'''

import sys

args = sys.argv[1:]

file1 = open(args[0], 'rb')
file2 = open(args[1], 'rb')
file_out = open(args[2], 'wb')

def get_bytes(file):
    '''Return a generator that yields each byte in the given file.'''
    def get_byte():
        return file.read(1)
    return iter(get_byte, b'')

for i, (byte1, byte2) in enumerate(zip(get_bytes(file1), get_bytes(file2))):
    if byte1 == byte2:
        byte_out = byte1
    elif ord(byte1) == 0:
        byte_out = byte2
    elif ord(byte2) == 0:
        byte_out = byte1
    else:
        msg = 'Bytes at {:#x} are both non-zero and do not match: {}, {}'
        raise ValueError(msg.format(i, byte1, byte2))
    file_out.write(byte_out)

Сделайте это, исполняемый файл затем называет его как так:

$ ./test.py file1.iso file2.iso file3.iso

Или если коротко:

$ ./test.py file{1,2,3}.iso

P.s. Я недавно изучал файлы чтения по-разному, таким образом, это - хорошая интуитивная прозорливость.

2
ответ дан 1 December 2019 в 16:50

Другие вопросы по тегам:

Похожие вопросы: