如何让grep用NULL字符分隔输出?

问题描述 投票:0回答:4

假设我们正在对一堆文件进行多行正则表达式模式搜索,并且我们想要从 grep 中提取匹配项。默认情况下,grep 输出由换行符分隔的匹配项,但由于我们正在执行多行模式,这会造成我们无法轻松提取单个匹配项的不便。

示例

grep -rzPIho '}\n\n\w\w\b' | od -a

根据文件树中的文件,这可能会产生类似的输出

0000000   }  nl  nl   m   y  nl   }  nl  nl   i   f  nl   }  nl  nl   m
0000020   y  nl   }  nl  nl   m   y  nl   }  nl  nl   i   f  nl   }  nl
0000040  nl   m   y  nl
0000044

如您所见,我们无法分割换行符来获取匹配项以供进一步处理,因为匹配项本身包含换行符。

什么不起作用

现在

--null
(或
-Z
)只能与
-l
一起使用,这使得 grep 只列出文件名而不是匹配项,所以这在这里没有帮助。

注意,这不是 Find 的 -print0 和 xargs 的 -0 开关有等效的 grep 吗?,因为该问题的要求不同,允许使用替代技术来回答。

那么,我们怎样才能做到这一点呢?也许将 grep 与其他工具结合使用?

bash unix grep text-processing null-character
4个回答
5
投票

因此,我将此问题作为功能请求提交到 GNU grep bug 邮件列表中,它似乎是代码中的一个错误。

它已被修复并推送到master,因此它将在GNU grep的下一个版本中可用:http://git.savannah.gnu.org/cgit/grep.git/commit/?id=cce2fd5520bba35cf9b264de2f1b6131304f19d2

总结一下:此补丁确保

-z
标志不仅可以与
-l
一起使用,还可以与
-o
一起使用。


1
投票

我想到的是使用组分隔符,例如:

grep -rzPIho '}\n\n\w\w\b' $FILE -H | sed "s/^$FILE:/\x0/"

1
投票

这是另一种方法,它应该比 @bufh 发布的更简单,但也更复杂和更慢。

$ grep -rIZl '' --include='*.pl'| xargs -0 cat | dos2unix | tr '\n\0' '\0\n' \
      | grep -Pao '}\x00\x00\w\w\b' | tr '\0\n' '\n\0' | od -a

显然只有在使用 Windows 行结尾时才需要 dos2unix。所以这里的要点是,我们将输入中的空字节与换行符交换,对空字节进行 grep 匹配,然后将内容交换回来。

0000000   }  nl  nl   m   y  nul   }  nl  nl   i   f  nul   }  nl  nl   m
0000020   y  nul   }  nl  nl   m   y  nul   }  nl  nl   i   f  nul   }  nl
0000040  nl   m   y  nul
0000044

0
投票

最新版本的 GNU grep 源现在可以使用 -z/--null 用空字符分隔输出,而以前它只能与 -l 结合使用:

http://git.savannah.gnu.org/cgit/grep.git/commit/?id=cce2fd5520bba35cf9b264de2f1b6131304f19d2

这意味着使用最新版本时您的问题会自动解决。

© www.soinside.com 2019 - 2024. All rights reserved.