tr 抱怨“非法字节序列”

use*_*886 33 grep character-encoding text-processing binary tr

我是 UNIX 的新手,我正在使用 Kirk McElhearn 的“Mac OS X 命令行”自学一些命令。

我正在尝试使用trandgrep以便我可以在常规 MS-Office Word 文档中搜索文本字符串。

$ tr '\r' '\n' < target-file | grep search-string
Run Code Online (Sandbox Code Playgroud)

但它返回的只是:

Illegal byte sequence.
Run Code Online (Sandbox Code Playgroud)

robomechanoid:Position-Paper-Final-Draft robertjralph$ tr '\r' '\n' < Position-Paper-Final-Version.docx | grep DeCSS
tr: Illegal byte sequence
robomechanoid:Position-Paper-Final-Draft robertjralph$ 
Run Code Online (Sandbox Code Playgroud)

我实际上在我创建的脚本上运行了同一行,vi并且它正确地进行了搜索。

Gil*_*il' 39

grep是一个文本处理工具。它期望他们的输入是文本文件tr在 macOS 上似乎也是如此(即使tr应该支持二进制文件)。

计算机将数据存储为字节序列。文本是一个字符序列。有多种将字符编码为字节的方法,称为字符编码。世界上大多数地方的事实上的标准字符编码,特别是在 OSX 上,是UTF-8,它是Unicode字符集的编码。只有 256 个可能的字节,但可能有超过一百万个 Unicode 字符,因此大多数字符都被编码为多个字节。UTF-8 是一种可变长度编码:根据字符的不同,编码一个字符可能需要一到四个字节。某些字节序列不代表 UTF-8 中的任何字符。因此,有些字节序列不是有效的 UTF-8 文本文件。

tr正在抱怨,因为它遇到了这样的字节序列。它希望看到一个以 UTF-8 编码的文本文件,但它看到的是无效的 UTF-8 二进制数据。

Microsoft Word 文档不是文本文件:它是文字处理文档。文字处理文档格式不仅对文本进行编码,还对格式、嵌入图像等进行编码。与大多数文字处理格式一样,Word 格式不是文本文件。

您可以通过更改语言环境来指示文本处理工具对字节进行操作。具体来说,选择“C”语言环境,这基本上意味着“没什么特别的”。在命令行上,您可以选择带有环境变量的区域设置。

export LC_CTYPE=C
tr '\r' '\n' < target-file | grep search-string
Run Code Online (Sandbox Code Playgroud)

这不会发出任何错误,但也不会做任何有用的事情,因为target-file它仍然是一个二进制文件,不太可能包含您将指定的大多数搜索字符串。

顺便说一句,tr '\r' '\n'除非您有 Mac OS 9 或更早版本遗留的文本文件,否则它不是一个非常有用的命令。\r(回车)是 Mac OS X 之前的 Mac OS 中的换行符。从 OSX 开始,换行符是\n(换行,unix 标准),文本文件不包含回车。Windows 使用两个字符的序列 CR-LF 来表示换行符;tr -d '\r'会将 Windows 文本文件转换为 Unix/Linux/OSX 文本文件。

那么如何从命令行搜索 Word 文档呢?一个.docxWord文件实际上是一个ZIP压缩文件包含多个文件,其中主要是在XML

unzip -l Position-Paper-Final-Version.docx
Run Code Online (Sandbox Code Playgroud)

Mac OS X 包含用于在 zip 文件中搜索的zipgrep实用程序。

zipgrep DeCSS Position-Paper-Final-Version.docx
Run Code Online (Sandbox Code Playgroud)

结果不会很可读,因为 docx 格式的 XML 文件大多由一大行组成。如果要在文档的正文中搜索,请word/document.xml从存档中提取文件。请注意,除了文档文本之外,该文件还包含表示文档结构的 XML 标记。您可以稍微调整 XML 标记sed以将其拆分为可管理的行。

unzip -p Position-Paper-Final-Version.docx word/document.xml |
sed -e 's/></>\n</g' |
grep DeCSS
Run Code Online (Sandbox Code Playgroud)

  • +1 表示良好的总结和额外的内容。不过我有一件事要说。要格式化 xml,您可以使用“xml_pp”,它位于 Debian Gnu+Linux 上的“xml-twig-tools”包中(不知道 Mac)。 (2认同)
  • Excel for Mac 2011 保存带有 \r 行结尾的 CSV 文件,因此此 tr 调用实际上非常相关且有用。 (2认同)

vin*_*c17 18

我想你的语言环境的charmap是UTF-8,所以你会在二进制文件上遇到问题。只需切换到 C 语言环境:

LC_ALL=C tr '\r' '\n' < target-file | LC_ALL=C grep search-string
Run Code Online (Sandbox Code Playgroud)