当前位置:  开发笔记 > 编程语言 > 正文

grepping二进制文件和UTF16

如何解决《grepping二进制文件和UTF16》经验,为你挑选了4个好方法。

标准grep/ pcregrep等可以方便地与二进制文件一起用于ASCII或UTF8数据 - 是否有一种简单的方法可以让它们尝试UTF16(最好是同时,但反过来会这样做)?

我试图获得的数据无论如何都是ASCII(库中的引用等),它只是找不到,因为有时两个字符之间有00,有时则没有.

我没有看到任何方法在语义上完成它,但是这些00应该可以解决问题,除了我不能在命令行上轻松使用它们.



1> Niki Yoshiuc..:

最简单的方法是将文本文件转换为utf-8并将其传递给grep:

iconv -f utf-16 -t utf-8 file.txt | grep query

我试图做相反的事情(将我的查询转换为utf-16),但似乎grep并不喜欢这样.我认为它可能与字节序有关,但我不确定.

好像grep会将utf-16的查询转换为utf-8/ascii.这是我尝试过的:

grep `echo -n query | iconv -f utf-8 -t utf-16 | sed 's/..//'` test.txt

如果test.txt是一个utf-16文件,这将不起作用,但如果test.txt是ascii,它确实有效.我只能得出结论,grep正在将我的查询转换为ascii.

编辑:这是一个非常疯狂的,有点工作,但没有给你非常有用的信息:

hexdump -e '/1 "%02x"' test.txt | grep -P `echo -n Test | iconv -f utf-8 -t utf-16 | sed 's/..//' | hexdump -e '/1 "%02x"'`

它是如何工作的?好吧,它将你的文件转换为十六进制(没有任何额外的格式,通常适用hexdump).它把它管成grep.Grep正在使用一个查询,该查询是通过将您的查询(没有换行符)回显到iconv中而构建的,该iconv将其转换为utf-16.然后将其传送到sed以删除BOM(用于确定字节序的utf-16文件的前两个字节).然后将其传送到hexdump,以便查询和输入相同.

不幸的是,如果只有一个匹配,我认为这将最终打印出整个ENTIRE文件.如果二进制文件中的utf-16以与机器不同的字节顺序存储,则此方法也不起作用.

EDIT2:搞定了!!!!

grep -P `echo -n "Test" | iconv -f utf-8 -t utf-16 | sed 's/..//' | hexdump -e '/1 "x%02x"' | sed 's/x/\\\\x/g'` test.txt

这将Test在文件中搜索字符串的十六进制版本(在utf-16中)test.txt


`iconv`不会起作用,因为它是一个二进制文件,很多非utf-16数据,并且`iconv`在第一次出错时退出.

2> Ethan Bradfo..:

您可以在搜索字符串中显式包含空值(00s),但是您将获得带有空值的结果,因此您可能希望将输出重定向到文件,以便您可以使用合理的编辑器查看它,或者将其通过sed传递给它替换空值.要在*.utf16.txt中搜索"bar":

grep -Pa "b\x00a\x00r" *.utf16.txt | sed 's/\x00//g'

"-P"告诉grep接受Perl regexp语法,它允许\ x00扩展为null,-a告诉它忽略Unicode看起来像二进制的事实.



3> nirmal..:

我发现以下解决方案最适合我,来自https://www.splitbits.com/2015/11/11/tip-grep-and-unicode/

Grep在Unicode方面表现不佳,但它可以解决.例如,找到,

Some Search Term

在UTF-16文件中,使用正则表达式忽略每个字符中的第一个字节,

S.o.m.e. .S.e.a.r.c.h. .T.e.r.m 

另外,告诉grep将文件视为文本,使用'-a',最后的命令如下所示,

grep -a 'S.o.m.e. .S.e.a.r.c.h. .T.e.r.m' utf-16-file.txt



4> 小智..:

转储Windows注册表后,由于它的输出是unicode,所以我一直都在使用它。这是在Cygwin下运行的。

$ regedit /e registry.data.out
$ file registry.data.out
registry.data.out: Little-endian **UTF-16 Unicode text**, with CRLF line terminators

$ sed 's/\x00//g' registry.data.out | egrep "192\.168"
"Port"="192.168.1.5"
"IPSubnetAddress"="192.168.189.0"
"IPSubnetAddress"="192.168.102.0"
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Print\Monitors\Standard TCP/IP Port\Ports\192.168.1.5]
"HostName"="192.168.1.5"
"Port"="192.168.1.5"
"LocationInformation"="http://192.168.1.28:1215/"
"LocationInformation"="http://192.168.1.5:80/WebServices/Device"
"LocationInformation"="http://192.168.1.5:80/WebServices/Device"
"StandaloneDhcpAddress"="192.168.173.1"
"ScopeAddressBackup"="192.168.137.1"
"ScopeAddress"="192.168.137.1"
"DhcpIPAddress"="192.168.1.24"
"DhcpServer"="192.168.1.1"
"0.0.0.0,0.0.0.0,192.168.1.1,-1"=""
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\Standard TCP/IP Port\Ports\192.168.1.5]
"HostName"="192.168.1.5"
"Port"="192.168.1.5"
"LocationInformation"="http://192.168.1.28:1215/"
"LocationInformation"="http://192.168.1.5:80/WebServices/Device"
"LocationInformation"="http://192.168.1.5:80/WebServices/Device"
"StandaloneDhcpAddress"="192.168.173.1"
"ScopeAddressBackup"="192.168.137.1"
"ScopeAddress"="192.168.137.1"
"DhcpIPAddress"="192.168.1.24"
"DhcpServer"="192.168.1.1"
"0.0.0.0,0.0.0.0,192.168.1.1,-1"=""
"MRU0"="192.168.16.93"
[HKEY_USERS\S-1-5-21-2054485685-3446499333-1556621121-1001\Software\Microsoft\Terminal Server Client\Servers\192.168.16.93]
"A"="192.168.1.23"
"B"="192.168.1.28"
"C"="192.168.1.200:5800"
"192.168.254.190::5901/extra"=hex:02,00
"00"="192.168.254.190:5901"
"ImagePrinterPort"="192.168.1.5"

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有