仅使用 sed 打印二进制匹配项?
Print binary matches only with sed?
让我们先来一个二进制测试文件:
echo -e '\x00\x01\x00\x0a\x00\x0f\x32\x7a\xb0\x00\x00\x01' > test.bin
hexdump -C test.bin
# 00000000 00 01 00 0a 00 0f 32 7a b0 00 00 01 0a |......2z.....|
# 0000000d
现在让我们看看我是否可以将字节序列 0x0f 0x32 0x7a 与 sed
:
匹配
sed -n 's/\(\x0f\x32\x7a\)//p' test.bin | hexdump -C
# 00000000 00 0f 32 7a b0 00 00 01 0a |..2z.....|
# 00000009
按预期工作 - 打印的匹配项是从最后一个换行符 0x0a 到 下一个 结尾。现在,我只想打印匹配 - 首先我尝试在开始时用 .*
正则表达式过滤掉:
sed -n 's/.*\(\x0f\x32\x7a\)//p' test.bin | hexdump -C
# 00000000 0f 32 7a b0 00 00 01 0a |.2z.....|
# 00000008
行得通 - 现在让我们做同样的事情,但也适用于尾随部分:
sed -n 's/.*\(\x0f\x32\x7a\).*//p' test.bin | hexdump -C
# 00000000 0f 32 7a b0 00 00 01 0a |.2z.....|
# 00000008
好吧,那 不 工作 - 只删除了标题部分 - 但尾随部分继续,即使我也终止了我的 sed
匹配模式.*
??!
这是怎么回事 - 我怎样才能让 sed
在输出中仅打印出字节 0x0f 0x32 0x7a(考虑到 hexdump
sed
将在打印匹配项时添加最后的换行符 0x0a)?
有意思。这是一个更简单的重现案例:
echo -en '\xff\x80' | sed -n 's/\xff.*/!/p' | hexdump -C
上面的打印 21 80
即 !\x80
。 \x80
也可以是更大的 ASCII 码,但不能更小:\x7F
让 sed
做预期的事情,只打印 !
.
另请查看它的作用:
echo -en '\xff\x80' | sed -n 's/\xff./!/p' | hexdump -C
它什么都不打印。
那么问题就变成了,\x80
及更高版本有什么特别之处?好吧,当然 UTF-8!在 UTF-8 中,设置代码点的第一位表示更多字节即将到来。 sed
永远找不到它们,所以它根本不会解释这个字符。
如果你想 "fix" 它,告诉 sed
使用 "good old" C 语言环境:
LC_ALL=C sed ...
然后你得到预期的输出:
echo -e '\x00\x01\x00\x0a\x00\x0f\x32\x7a\xb0\x00\x00\x01' |
LC_ALL=C sed -n 's/.*\(\x0f\x32\x7a\).*//p' |
hexdump -C
00000000 0f 32 7a 0a |.2z.|
让我们先来一个二进制测试文件:
echo -e '\x00\x01\x00\x0a\x00\x0f\x32\x7a\xb0\x00\x00\x01' > test.bin
hexdump -C test.bin
# 00000000 00 01 00 0a 00 0f 32 7a b0 00 00 01 0a |......2z.....|
# 0000000d
现在让我们看看我是否可以将字节序列 0x0f 0x32 0x7a 与 sed
:
sed -n 's/\(\x0f\x32\x7a\)//p' test.bin | hexdump -C
# 00000000 00 0f 32 7a b0 00 00 01 0a |..2z.....|
# 00000009
按预期工作 - 打印的匹配项是从最后一个换行符 0x0a 到 下一个 结尾。现在,我只想打印匹配 - 首先我尝试在开始时用 .*
正则表达式过滤掉:
sed -n 's/.*\(\x0f\x32\x7a\)//p' test.bin | hexdump -C
# 00000000 0f 32 7a b0 00 00 01 0a |.2z.....|
# 00000008
行得通 - 现在让我们做同样的事情,但也适用于尾随部分:
sed -n 's/.*\(\x0f\x32\x7a\).*//p' test.bin | hexdump -C
# 00000000 0f 32 7a b0 00 00 01 0a |.2z.....|
# 00000008
好吧,那 不 工作 - 只删除了标题部分 - 但尾随部分继续,即使我也终止了我的 sed
匹配模式.*
??!
这是怎么回事 - 我怎样才能让 sed
在输出中仅打印出字节 0x0f 0x32 0x7a(考虑到 hexdump
sed
将在打印匹配项时添加最后的换行符 0x0a)?
有意思。这是一个更简单的重现案例:
echo -en '\xff\x80' | sed -n 's/\xff.*/!/p' | hexdump -C
上面的打印 21 80
即 !\x80
。 \x80
也可以是更大的 ASCII 码,但不能更小:\x7F
让 sed
做预期的事情,只打印 !
.
另请查看它的作用:
echo -en '\xff\x80' | sed -n 's/\xff./!/p' | hexdump -C
它什么都不打印。
那么问题就变成了,\x80
及更高版本有什么特别之处?好吧,当然 UTF-8!在 UTF-8 中,设置代码点的第一位表示更多字节即将到来。 sed
永远找不到它们,所以它根本不会解释这个字符。
如果你想 "fix" 它,告诉 sed
使用 "good old" C 语言环境:
LC_ALL=C sed ...
然后你得到预期的输出:
echo -e '\x00\x01\x00\x0a\x00\x0f\x32\x7a\xb0\x00\x00\x01' |
LC_ALL=C sed -n 's/.*\(\x0f\x32\x7a\).*//p' |
hexdump -C
00000000 0f 32 7a 0a |.2z.|