
しばらく前に、死にかけの HDD を 2 回修復しようとしました。ddrescue
最初に (GNU) を実行し、その後、dd
手動で直接シークしました。両方のイメージの最良の部分を取得したいのです。ファイル内の空の部分は 0 だけなので、2 つのファイルを結合するにはビット単位の AND で十分です。
2 つの入力ファイルの OR であるファイルを作成できるユーティリティはありますか?
(私は ArchLinux を使用していますが、リポジトリにない場合はソースからインストールしても構いません)
答え1
これを実行するユーティリティは知りませんが、これを行うプログラムを書くのはかなり簡単なはずです。以下は Python での骨組みの例です。
#!/usr/bin/env python
f=open("/path/to/image1","rb")
g=open("/path/to/image2","rb")
h=open("/path/to/imageMerge","wb") #Output file
while True:
data1=f.read(1) #Read a byte
data2=g.read(1) #Read a byte
if (data1 and data2): #Check that neither file has ended
h.write(chr(ord(data1) | ord(data2))) #Or the bytes
elif (data1): #If image1 is longer, clean up
h.write(data1)
data1=f.read()
h.write(data1)
break
elif (data2): #If image2 is longer, clean up
h.write(data2)
data2=g.read()
h.write(data2)
break
else: #No cleanup needed if images are same length
break
f.close()
g.close()
h.close()
または、より高速に実行されるはずの C プログラム (ただし、気付かれないバグが存在する可能性が大幅に高くなります)。
#include <stdio.h>
#include <string.h>
#define BS 1024
int main() {
FILE *f1,*f2,*fout;
size_t bs1,bs2;
f1=fopen("image1","r");
f2=fopen("image2","r");
fout=fopen("imageMerge","w");
if(!(f1 && f2 && fout))
return 1;
char buffer1[BS];
char buffer2[BS];
char bufferout[BS];
while(1) {
bs1=fread(buffer1,1,BS,f1); //Read files to buffers, BS bytes at a time
bs2=fread(buffer2,1,BS,f2);
size_t x;
for(x=0;bs1 && bs2;--bs1,--bs2,++x) //If we have data in both,
bufferout[x]=buffer1[x] | buffer2[x]; //write OR of the two to output buffer
memcpy(bufferout+x,buffer1+x,bs1); //If bs1 is longer, copy the rest to the output buffer
memcpy(bufferout+x,buffer2+x,bs2); //If bs2 is longer, copy the rest to the output buffer
x+=bs1+bs2;
fwrite(bufferout,1,x,fout);
if(x!=BS)
break;
}
}
答え2
パイソン
with open('file1', 'rb') as in1, open('file2', 'rb') as in2, open('outfile', 'wb') as out:
while True:
bytes1 = in1.read(1024)
bytes2 = in2.read(1024)
if not bytes1 or not bytes2:
break
out.write(bytes(b1 | b2 for (b1, b2) in zip(bytes1, bytes2)))
これは、一度に 1024 バイトを読み取るため、Chris の Python ソリューションよりも約 10 倍高速です。また、with open
ファイルを閉じるときに信頼性が高いため (エラーの場合など)、パターンも使用します。
これは Python 3.6.3 で動作するようです (2 つの部分的な torrent ファイルを正常にマージ) が、徹底的にテストされていません。
おそらくif ...: break
パターンを削除して代わりにwhile in1 or in2:
答え3
これはビット単位の論理和ではありませんが、ゼロのブロック全体に対して機能します。
dd conv=sparse,notrunc if=foo of=baz
dd conv=sparse,notrunc if=bar of=baz
これにより、sparse
ソース ファイル内のゼロの書き込みがスキップされます。
したがって、baz は bar のようになり、さらに bar ではゼロだったが foo ではゼロではなかったものも加算されます。
つまり、foo と bar に同一ではない非ゼロデータがある場合は、bar が勝ちます。