标准grep
/ pcregrep
等可以方便地与二进制文件一起用于ASCII或UTF8数据 - 是否有一种简单的方法可以让它们尝试UTF16(最好是同时,但反过来会这样做)?
我试图获得的数据无论如何都是ASCII(库中的引用等),它只是找不到,因为有时两个字符之间有00,有时则没有.
我没有看到任何方法在语义上完成它,但是这些00应该可以解决问题,除了我不能在命令行上轻松使用它们.
最简单的方法是将文本文件转换为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
您可以在搜索字符串中显式包含空值(00s),但是您将获得带有空值的结果,因此您可能希望将输出重定向到文件,以便您可以使用合理的编辑器查看它,或者将其通过sed传递给它替换空值.要在*.utf16.txt中搜索"bar":
grep -Pa "b\x00a\x00r" *.utf16.txt | sed 's/\x00//g'
"-P"告诉grep接受Perl regexp语法,它允许\ x00扩展为null,-a告诉它忽略Unicode看起来像二进制的事实.
我发现以下解决方案最适合我,来自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
转储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"