从文件开头删除字节的最佳方法?

从文件开头删除字节的最佳方法?

今天,我必须从一个 800MB 的混合文本/二进制文件中删除前 1131 个字节,这是一个经过过滤的颠覆转储,我正在为一个新的存储库进行黑客攻击。最好的方法是什么?

首先我尝试过

dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump

但在跳过之后,它一次复制文件的其余部分一个字节,即非常慢。最后我发现我需要 405 个字节才能将其四舍五入到三个 512 块,我可以跳过它

dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump

完成得相当快,但一定有更简单/更好的方法?还有其他我忘记的工具吗?

答案1

您可以切换 bs 并跳过选项:

dd bs=1131 skip=1 if=filtered.dump of=trimmed.dump

这样操作就可以从更大的块中受益。

否则,您可以尝试使用 tail (尽管将其与二进制文件一起使用并不安全):

tail -c +1132 filtered.dump >trimmed.dump

最后,你可以使用 3 个 dd 实例来编写如下内容:

dd if=filtered.dump bs=512k | { dd bs=1131 count=1 of=/dev/null; dd bs=512k of=trimmed.dump; }

其中第一个 dd 打印其标准输出filtered.dump;第二个只读取 1131 字节并将其丢弃;然后,最后一个从其标准输入读取filtered.dump的剩余字节并将它们写入trimmed.dump。

答案2

不确定何时skip_bytes添加,但要跳过前 11 个字节:

# echo {123456789}-abcdefgh- | 
                              dd bs=4096 skip=11 iflag=skip_bytes
-abcdefgh-
0+1 records in
0+1 records out
11 bytes (11 B) copied, 6.963e-05 s, 158 kB/s

whereiflag=skip_bytes告诉 dd 将选项的值解释skip为字节而不是块,使其变得简单。

答案3

您可以使用子 shell 和两个dd调用,如下所示:

$ ( dd bs=1131 count=1 of=dev_null && dd bs=4K of=out.mp3 ) < 100827_MR029_LobbyControl.mp3
1+0 records in
1+0 records out
1131 bytes (1.1 kB) copied, 7.9691e-05 s, 14.2 MB/s
22433+1 records in
22433+1 records out
91886130 bytes (92 MB) copied, 0.329823 s, 279 MB/s
$ ls -l *
-rw------- 1 max users 91887261 2011-02-03 22:59 100827_MR029_LobbyControl.mp3
-rw-r--r-- 1 max users     1131 2011-02-03 23:04 dev_null
-rw-r--r-- 1 max users 91886130 2011-02-03 23:04 out.mp3
$ cat dev_null out.mp3 > orig
$ cmp 100827_MR029_LobbyControl.mp3 orig

答案4

您应该尽可能使用count=0- 这是一个简单的方法。lseek()

像这样:

{  dd bs=1131 skip=1 count=0; cat; } <filtered.dump >trimmed.dump

ddlseek()输入文件描述符移动到 1131 字节偏移量,然后cat简单地将剩余的内容复制到输出。

相关内容