所以,我正在搞乱bash,并且意外地将几个具有.txt扩展名的.jpg文件合并到一个.jpg中。我写的愚蠢是
mv ./*.txt .jpg
关于如何撤消它的任何想法?创建的文件的大小与所有合并的其他文件的大小兼容,所以我猜它就在那里,但是无法想出如何分离二进制文件......
(是的,为什么我这样做呢?谁知道呢)
感谢您的帮助。
答案 0 :(得分:3)
JPEG文件以d8ff
作为JPEG标记开头。所以,十六进制转储你的文件和grep d8ff
:
od -x yourTextfile.txt | grep d8ff
然后获取字节偏移量,并使用dd
提取文件。因此,如果在地址2048处看到JPEG标记,请执行以下操作:
dd if=yourTextFile bs=1 iseek=2048 > file1.jpg
您需要将blocksize设置为1(bs=1
),以使偏移量以字节为单位而不是512字节块。有些dd
版本比skip
更喜欢iseek
。
注意:您将在JPEG文件的末尾获得无关的垃圾,但大多数图片编辑都会忽略它。
<强>更新强>
这是一种在Perl中恢复文件的稍微漂亮的方法...
#!/usr/bin/perl
use strict;
use warnings;
my $contents;
my $i=0;
# Slurp entire file
{
local $/ = undef;
open FILE, "file.txt" or die "Couldn't open file: $!";
$contents = <FILE>;
close FILE;
}
while((my $offset=index($contents,"\xff\xd8"))!=-1){
my $filename=sprintf("recovered_%d.jpg",$i++);
printf "Recovering at offset: $offset into file: $filename\n";
open(OUTFILE,">$filename");
print OUTFILE substr($contents,$offset,10000000);
close(OUTFILE);
substr($contents,$offset,2)="\x00\x00"; # Overwrite this header so we find another next time
}
Uglier shell版本:
你可以用这样的代码编写代码 - 快速而脏的代码警告!!!
#!/bin/bash
file=file.txt # Edit with the name of your text file with all JPEGs in it
n=0
od -Ad -b "$file" | \
awk '/377 330 377 340/ {for(i=2;i<NF-4;i++)
if($i=="377" && $(i+1)=="330" && $(i+2)=="377" && $(i+3)=="340")
print $1+i-2
}' | \
while read offset; do
name="recovered_${n}.jpg"
echo Possible JPEG at offset $offset - recovering following 10MB as $name
dd if="$file" of="$name" bs=1 iseek=$offset count=10000000
((n++))
done
如果你运气不好,图片的标题可能跨越od
输出的两行,在这种情况下,377 330 377 340
不会全部在同一行和脚本上不会找到那个图像。我建议您运行脚本一次并将所有恢复的文件复制到另一个目录(以保存它们)然后再次运行它,而不是在文件的开头添加4个或更多字节以强制执行将整个JPEG签名放到下一行,如下所示:
(echo spacer; cat file.txt ) > file2.txt
然后再次运行脚本,但这次是file2.txt
。