locate
我经常使用(from findutils
) and的以下管道grep
来查找路径名包含两个单词word1
and的文件word2
,彼此之间没有任何特定的顺序:
locate -i word1 | grep -i word2
我想知道如何单独使用单个非管道命令来做到这一点?这是比我的管道命令更好的方法吗?
是否locate
支持一些正则表达式,我们可以在其中制定我的搜索模式?
谢谢。
答案1
这很大程度上取决于您的实施locate
。这不是一个标准命令,有一些不同的实现,它们之间存在相当大的差异。
GNU findutils 中有一种实现。
与那个:
locate -i word1 word2
查找路径包含
word1
或word2
不区分大小写的文件locate -Ai word1 word2
查找路径同时包含两者的文件。
它还支持类似于 GNU 的
--regex
和选项。默认情况下,这是-style 正则表达式,是 BRE 和 ERE 之间的某种形式的混合体。--regextype
find
emacs
有了这个,你可以这样做:
locate -ir 'word1.*word2\|word2.*word1'
实现
mlocate
(Debian 及其衍生版本上的默认实现)也支持-A
。它有-r
/--regex
,但没有--regextype
,并且它的 RE 是基本正则表达式。在 GNU 等 BRE 支持\|
交替扩展的系统上,您还可以执行以下操作:locate -ir 'word1.*word2\|word2.*word1'
ast-open 有一个
locate
以及一个 ksh93 包装脚本tw
(曾经是 的后继者find
)。它不支持-A
nor-r
,但您可以使用通配符的全部功能ksh93
,因此您可以使用例如类似perl的前瞻运算符:locate '~(Pi:^(?=.*word1)(?=.*word2))'
Or
ksh93
的&
全局运算符:locate -i '*word1*&*word2*'
尽管该模式未锚定,但与其他模式相比,它特别慢。一旦锚定(
l
左向和r
右向)恢复后效果会更好:locate -i '~(lr)*word1*&*word2*'
管道连接的一个问题grep
是它不适用于包含换行符的文件路径。通过 GNUlocate 或 mlocate,您可以使用该选项来使用 NUL 分隔的记录,您可以将其与GNU 的选项-0
结合使用:-z
grep
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/'