【问题标题】:Unable to grep output of python program, possible utf-16无法 grep 输出 python 程序,可能是 utf-16
【发布时间】:2012-10-09 05:31:49
【问题描述】:

我写了一个基本的python程序来解析android的resources.arsc。它打印出在文件中找到的所有字符串。字符串在每个字符之间有一个零值字节。这向我表明字符串存储在 utf-16 中。我不知道这是否正确,但 android 字符串是可本地化的,所以我认为是。我正在使用 string.decode('hex') 以人类可读的格式打印字符串。这是一个包含组成字符串的字节列表的示例:

>>> print ''.join(['00', '72', '00', '65', '00', '73', '00', '2f', '00', '64', '00', '72',    '00', '61', '00', '77', '00', '61', '00', '62', '00', '6c', '00', '65', '00', '2f', '00', '61', '00', '62', '00', '6f', '00', '75', '00', '74', '00', '2e', '00', '70', '00', '6e', '00', '67', '00', '00', '00']).decode('hex')
res/drawable/about.png

问题是,当我将此程序通过管道传输到 grep 时,我无法对读取的任何字符串进行 grep。如何将其打印到 shell 以便 grep 能够在其输出中匹配?谢谢!

(编辑)我确实打印了字符串,但在我的示例中,我认为最好同时显示“打印”版本和返回的版本。对困惑感到抱歉。在此示例中,无法 grep 的是“/res/drawable/about.png”。

(EDIT2) 一个简单的演示:

11:33 AM ~/learning_python $ python -c "print ''.join(['00', '72', '00', '65', '00', '73', '00', '2f', '00', '64', '00', '72',    '00', '61', '00', '77', '00', '61', '00', '62', '00', '6c', '00', '65', '00', '2f', '00', '61', '00', '62', '00', '6f', '00', '75', '00', '74', '00', '2e', '00', '70', '00', '6e', '00', '67', '00', '00', '00']).decode('hex')"
res/drawable/about.png
11:33 AM ~/learning_python $ python -c "print ''.join(['00', '72', '00', '65', '00', '73', '00', '2f', '00', '64', '00', '72',    '00', '61', '00', '77', '00', '61', '00', '62', '00', '6c', '00', '65', '00', '2f', '00', '61', '00', '62', '00', '6f', '00', '75', '00', '74', '00', '2e', '00', '70', '00', '6e', '00', '67', '00', '00', '00']).decode('hex')" | grep about
11:33 AM ~/learning_python $ 

(EDIT3)另一个演示,我认为这证明数据是utf-16-be:

11:33 AM ~/learning_python $ python -c "print ''.join(['00', '72', '00', '65', '00', '73', '00', '2f', '00', '64', '00', '72',    '00', '61', '00', '77', '00', '61', '00', '62', '00', '6c', '00', '65', '00', '2f', '00', '61', '00', '62', '00', '6f', '00', '75', '00', '74', '00', '2e', '00', '70', '00', '6e', '00', '67', '00', '00', '00']).decode('hex')" > testfile
11:35 AM ~/learning_python $ iconv -f utf16be -t utf8 testfile
res/drawable/about.png
11:35 AM ~/learning_python $ iconv -f utf16be -t utf8 testfile | grep about
Binary file (standard input) matches
11:35 AM ~/learning_python $ iconv -f utf16be -t utf8 testfile | grep -a about
res/drawable/about.png

【问题讨论】:

  • 你是否“打印”了解码后的字符串?
  • 是的,这就是最终字符串的生成方式。为了清楚起见,我编辑了我的问题。
  • 把所有的东西放在一个数组中,你会注意到概率 python -c "p​​rint [''.join(['00', '72', '00', '65', '00' , '73', '00', '2f', '00', '64', '00', '72', '00', '61', '00', '77', '00', ' 61'、'00'、'62'、'00'、'6c'、'00'、'65'、'00'、'2f'、'00'、'61'、'00'、'62' ,'00','6f','00','75','00','74','00','2e','00','70','00','6e',' 00', '67', '00', '00', '00']).decode('hex')]"

标签: python grep utf-16


【解决方案1】:

解码字符:

'\x00r\x00e\x00s'.decode('utf-16-be') # produces u'res'

然后就可以打印出解码后的字符串了:

$ python -c "print ''.join(['00', '72', '00', '65', '00', '73', '00', '2f', '00', '64', '00', '72',    '00', '61', '00', '77', '00', '61', '00', '62', '00', '6c', '00', '65', '00', '2f', '00', '61', '00', '62', '00', '6f', '00', '75', '00', '74', '00', '2e', '00', '70', '00', '6e', '00', '67', '00', '00', '00', '00']).decode('hex').decode('utf-16-be').rstrip('\0')" | grep about
res/drawable/about.png

【讨论】:

  • 谢谢...我现在可以 grep 程序的输出,但我必须使用 -a 开关。我可以忍受:)
【解决方案2】:

使用ripgrep utility 代替可以支持UTF-16 文件的grep

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

示例语法:

rg sometext file

【讨论】:

    猜你喜欢
    • 2014-06-22
    • 2011-03-31
    • 2012-03-16
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    • 2010-12-24
    • 2012-02-23
    相关资源
    最近更新 更多