And*_*ier 41 unix bash grep find xargs
我经常想写这样的命令(zsh如果它是相关的):
find <somebasedirectory> | \
    grep stringinfilenamesIwant | \
    grep -v stringinfilesnamesIdont | \
    xargs dosomecommand
(或更复杂的greps组合)
近年来find添加了-print0交换机,并添加了xargs -0,它允许通过空终止文件名来优雅地处理名称中带有空格的文件,从而允许:
find <somebasedirectory> -print0 | xargs -0 dosomecommand
但是,grep(至少我拥有的版本,Ubuntu上的GNU grep 2.10),似乎没有等效消耗并生成以null结尾的行; 它有--null,但这似乎只与使用-lgrep直接搜索文件时输出名称有关.
我可以使用与grep相同的选项或选项组合吗?或者,是否有一种简单而优雅的方式来表达我的命令管道,只需使用find -regex或Perl?
Tod*_*obs 43
--null标志根据GNU Grep文档,您可以使用输出行前缀控件来处理ASCII NUL字符,方法与find和xargs相同.
-Z
--null
输出零字节(ASCII NUL字符),而不是通常跟随文件名的字符.例如,'grep -lZ'在每个文件名后输出一个零字节,而不是通常的换行符.即使存在包含不常用字符(如换行符)的文件名,此选项也会使输出明确无误.此选项可与"find -print0","perl -0","sort -z"和"xargs -0"等命令一起使用,以处理任意文件名,甚至是包含换行符的文件名.
trGNU Coreutils正如OP正确指出的那样,在处理输入或输出上的文件名时,此标志最有用.为了实际转换grep输出以使用NUL字符作为行结尾,您需要使用像sed或tr这样的工具来转换每行输出.例如:
find /etc/passwd -print0 |
    xargs -0 egrep -Z 'root|www' |
    tr "\n" "\0" |
    xargs -0 -n1
此管道将使用NUL将文件名与find分开,然后将换行符转换为egrep返回的字符串中的NUL.这会将NUL终止的字符串传递给管道中的下一个命令,在这种情况下只是xargs将输出转换回普通字符串,但它可能是你想要的任何东西.
由于您已经在使用GNU find,因此可以使用其内部正则表达式模式匹配功能,而不是这些grep,例如:
find <somebasedirectory> -regex ".*stringinfilenamesIwant.*" ! -regex ".*stringinfilesnamesIdont.*" -exec dosomecommand {} + 
| 归档时间: | 
 | 
| 查看次数: | 14857 次 | 
| 最近记录: |