使用locate和grep管道改进按路径名搜索文件

使用locate和grep管道改进按路径名搜索文件

locate我经常使用(from findutils) and的以下管道grep来查找路径名包含两个单词word1and的文件word2,彼此之间没有任何特定的顺序:

locate -i word1 | grep -i  word2

我想知道如何单独使用单个非管道命令来做到这一点?这是比我的管道命令更好的方法吗?

是否locate支持一些正则表达式,我们可以在其中制定我的搜索模式?

谢谢。

解决方案findhttps://unix.stackexchange.com/a/448006/674

答案1

这很大程度上取决于您的实施locate这不是一个标准命令,有一些不同的实现,它们之间存在相当大的差异。

  1. GNU findutils 中有一种实现。

    与那个:

    locate -i word1 word2
    

    查找路径包含word1word2不区分大小写的文件

    locate -Ai word1 word2
    

    查找路径同时包含两者的文件。

    它还支持类似于 GNU 的 --regex和选项。默认情况下,这是-style 正则表达式,是 BRE 和 ERE 之间的某种形式的混合体。--regextypefindemacs

    有了这个,你可以这样做:

    locate -ir 'word1.*word2\|word2.*word1'
    
  2. 实现mlocate(Debian 及其衍生版本上的默认实现)也支持-A。它有-r/ --regex,但没有 --regextype,并且它的 RE 是基本正则表达式。在 GNU 等 BRE 支持\|交替扩展的系统上,您还可以执行以下操作:

    locate -ir 'word1.*word2\|word2.*word1'
    
  3. ast-open 有一个locate以及一个 ksh93 包装脚本tw(曾经是 的后继者find。它不支持-A nor -r,但您可以使用通配符的全部功能ksh93,因此您可以使用例如类似perl的前瞻运算符:

    locate '~(Pi:^(?=.*word1)(?=.*word2))'
    

    Orksh93&全局运算符:

    locate -i '*word1*&*word2*'
    

    尽管该模式未锚定,但与其他模式相比,它特别慢。一旦锚定(l左向和 r右向)恢复后效果会更好:

    locate -i '~(lr)*word1*&*word2*'
    

管道连接的一个问题grep是它不适用于包含换行符的文件路径。通过 GNUlocate 或 mlocate,您可以使用该选项来使用 NUL 分隔的记录,您可以将其与GNU 的选项-0结合使用:-zgrep

locate -i0 word1 | grep -z word2 | grep -z word3 | tr '\0' '\n'

或者-v RS='\0'在 GNU gawk 或 @ThomasDickey 中mawk

locate -i0 word1 | awk -v RS='\0' '/word2/ && /word3/'

或者perl -ln0

locate -i0 word1 | perl -ln0e 'print if /word2/ && /word3/'

相关内容