首页 > 解决方案 > 带有重定向的 Grep 给出空字节

问题描述

我的 grep 命令在其输出末尾生成一个 NUL 字节。

我有file.xml其中仅包含:

<Game>
    <Player p1="Bob"/>
    <Player p2="Fred"/>
</Game>

现在运行grep -Pzo '<Game>(\n|.)*?(</Game>)'给出了预期的输出:

<Game>
        <Player p1="Bob"/>
        <Player p2="Fred"/>
</Game>

grep -Pzo '<Game>(\n|.)*?(</Game>)' file.xml > out.md但是,当在 Notepad++ 中打开时,重定向输出会在文件末尾显示 NUL 字节,并在 Sublime 中作为二进制文件打开:

3c47 616d 653e 0a09 3c50 6c61 7965 7220
7031 3d22 426f 6222 2f3e 0a09 3c50 6c61
7965 7220 7032 3d22 4672 6564 222f 3e0a
3c2f 4761 6d65 3e00 

其他 grep 命令不会发生这种情况,例如grep -rlF "Game" > out.md.

标签: grepbinarynul

解决方案


不知道使用哪个平台和 grep 版本,但我会省略 -z 选项:

GNU grep 3.0 文档

-z--null-data   
Treat input and output data as sequences of lines, each terminated by a zero byte (the ASCII NUL character) instead of a newline. Like the -Z or --null option, this option can be used with commands like ‘sort -z’ to process arbitrary file names. 

file.xml 的十六进制:

0000000: 3c47 616d 653e 0a20 2020 203c 506c 6179  <Game>.    <Play
0000010: 6572 2070 313d 2242 6f62 222f 3e0a 2020  er p1="Bob"/>.
0000020: 2020 3c50 6c61 7965 7220 7032 3d22 4672    <Player p2="Fr
0000030: 6564 222f 3e0a 3c2f 4761 6d65 3e0a       ed"/>.</Game>.

所以运行:

grep -Po '<Game>(\n|.)*?(</Game>)' file.xml > out.md

out.md 的十六进制:

0000000: 3c47 616d 653e 0a20 2020 203c 506c 6179  <Game>.    <Play
0000010: 6572 2070 313d 2242 6f62 222f 3e0a 2020  er p1="Bob"/>.
0000020: 2020 3c50 6c61 7965 7220 7032 3d22 4672    <Player p2="Fr
0000030: 6564 222f 3e0a 3c2f 4761 6d65 3e0a       ed"/>.</Game>.

推荐阅读