2

我有一个大文件,我想从中删除一些内容,该文件是二进制文件,而且我没有行号,而是十六进制地址,所以我怎样才能删除之间的区域:
0x13e70a00 和 0x1eaec03ff
使用 sed(包括)

这样的事情会奏效吗?

sed -n 's/\x13e70a00/,s/\x1eaec03ff/ p' orig-data-file > new-file
4

2 回答 2

3

从您写的内容来看,您似乎正在尝试删除两个十六进制模式之间的所有字节。为此,您将需要

这将删除模式之间的所有字节,包括模式。

 sed 's/\x13\xe7\x0a\x00.*\x1e\xae\xc0\x3f//g' in >out

这将删除模式之间的所有字节,使模式保持不变。(有一种方法可以使用正则表达式的编号部分,但这更清楚一些)

 sed 's/\x13\xe7\x0a\x00.*\x1e\xae\xc0\x3f/\x13\xe7\x0a\x00\x1e\xae\xc0\x3f/g' in >out

他们搜索s/a<pattern1>后跟任何文本.*,然后<pattern2>将其替换为任何内容或仅在整个文件//g中的两个边缘/<pattern1><pattern2>/g/g

如果要删除(或替换)字节 300 到字节 310:

sed 's/\(.\{300\}\).\{10\}/\1rep-str/' in>out

这匹配前 300 个字符 ( .\{300\}) 并记住它们 (the \(\))。它也匹配接下来的 10 个字符。它用前 300 个字符\1rep-str

但是,如果有任何换行符,这将非常脆弱。如果您无需更换就可以生活:

dd if=file bs=1 skip=310|dd of=file bs=1 seek=300 conv=notrunc

这通过从第 310 个字节开始复制直到从 300 位置开始的文件中进行就地替换,从而删除 10 个字节

一个更普遍的选择是

dd if=in bs=1 count=300>out
printf "replacement text">>out
dd if=in bs=1 skip=310>>out

虽然最简单的方法是使用像 Bless 这样的十六进制编辑器

于 2013-07-30T09:49:29.107 回答
2

您应该能够使用巧妙的组合将 bash 数字从 hex 转换为 decimalbash math将 1 添加到小数偏移量,并cut --complement -b从文件中删除正确的段。

编辑:像这样:

$ snip_out 0x0f 0x10 <<< "0123456789abcdeffedcba9876543210" | od -t x1
0000000 30 31 32 33 34 35 36 37 38 39 61 62 63 64 65 65
0000020 64 63 62 61 39 38 37 36 35 34 33 32 31 30
0000036

snip_out在stdin 和 stdout 上运行的两参数 shell 脚本在哪里:

#!/bin/bash

START_RANGE_DEC=$(printf "%d" $1)
END_RANGE_DEC=$(printf "%d" $2)

# Most hex ranges begin with 0; cut begins with 1.
CUT_START_DEC=$(( $START_RANGE_DEC + 1 ))
CUT_END_DEC=$(( $END_RANGE_DEC + 1 ))

# cut likes to append a newline after output. Use head to remove it.
exec cut --complement -b $CUT_START_DEC-$CUT_END_DEC | head -c -1
于 2013-07-30T00:01:22.653 回答