我有一个损坏的磁盘映像文件(约 27 GB),其中所有 \n 字符之前都插入了 \r\r。我想删除所有 \n 之前的这些 \r\r。
我尝试用 awk:
awk '{ sub("\r\r$", ""); print }' mangled.raw > image.raw
但该文件似乎太大:“awk:运行时错误:内存不足”
我也尝试用 sed:
sed 's/\r\r$//g' mangled.raw > image.raw
但这里的输出文件似乎不完整:它只有 20 GB 大小,并且 mangled.raw 的末尾包含许多零字符,而 image.raw 的末尾包含文件的内容。不知何故,sed 似乎在结束之前停止了。
知道如何正确地做到这一点吗?
答案1
Eldering 的评论可能是正确的 - 这取决于损坏是如何发生的。如果它做了等同于s/\n/\r\r\n/
那么它是可逆的,但如果它做了s/\r*\n/\r\r\n/
那么它就不是。
无论如何,我会使用 perl 来处理这样的事情。与 sed 不同,它从一开始就被设计用于处理非常长的字符串,并且可以包含 NUL 和其他非文本字符。
perl -pe 's/\r\r\n/\n/g' mangled.raw > image.raw
这可能会消耗大量内存,因为它仍然将文件读取为一系列行,并且文件中可能有很大部分没有行,这些\n
行将被视为单个“行”。但是,如果您按块读取,则必须小心,不要错过\r\r\n
跨越块边界的序列。像这样:
perl -e '
$/=\65536;
while(<>) {
if(/\r\z/) {
if(length($nextblock=<>)) {
$_.=$nextblock;
redo;
}
}
s/\r\r\n/\n/g;
print;
}
' mangled.raw > image.raw
编辑:我意识到如果输入的最后一个字节是,上述代码将陷入无限循环\r
。它已更新以正确处理这种情况。
编辑2:perl 单行代码包含错误的替换字符。已更新。