grepping二进制文件和UTF16

taw*_*taw 61 unicode grep utf-16

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

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

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

Nik*_*chi 66

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

iconv -f utf-16 -t utf-8 file.txt | grep query
Run Code Online (Sandbox Code Playgroud)

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

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

grep `echo -n query | iconv -f utf-8 -t utf-16 | sed 's/..//'` test.txt
Run Code Online (Sandbox Code Playgroud)

如果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"'`
Run Code Online (Sandbox Code Playgroud)

它是如何工作的?好吧,它将你的文件转换为十六进制(没有任何额外的格式,通常适用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
Run Code Online (Sandbox Code Playgroud)

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

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

Eth*_*ord 14

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

grep -Pa "b\x00a\x00r" *.utf16.txt | sed 's/\x00//g'
Run Code Online (Sandbox Code Playgroud)

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


ken*_*orb 11

ripgrep

使用ripgrep实用程序grep UTF-16 文件。

ripgrep 支持搜索 UTF-8 以外的文本编码的文件,例如 UTF-16、latin-1、GBK、EUC-JP、Shift_JIS 等。(提供了对自动检测 UTF-16 的一些支持。其他文本编码必须使用-E/专门指定--encoding flag.

语法示例:

rg sometext file
Run Code Online (Sandbox Code Playgroud)

要转储所有行,请运行:rg -N . file


nir*_*mal 10

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

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

Some Search Term
Run Code Online (Sandbox Code Playgroud)

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

S.o.m.e. .S.e.a.r.c.h. .T.e.r.m 
Run Code Online (Sandbox Code Playgroud)

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

grep -a 'S.o.m.e. .S.e.a.r.c.h. .T.e.r.m' utf-16-file.txt
Run Code Online (Sandbox Code Playgroud)


Dr.*_* RE 7

ugrep(通用grep)完全支持Unicode、UTF-8/16/32输入文件,检测无效的Unicode以确保正确的结果,显示文本和二进制文件,并且快速且免费:

ugrep搜索 UTF-8/16/32 输入和其他格式。该选项--encoding允许搜索许多其他文件格式,例如 ISO-8859-1 至 16、EBCDIC、代码页 437、850、858、1250 至 1258、MacRoman 和 KOI8。

有关详细信息,请参阅GitHub 上的 ugrep


小智 5

转储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"
Run Code Online (Sandbox Code Playgroud)