Melhore a pesquisa de arquivos por nomes de caminho com o pipeline locate e grep

1

Costumo usar o seguinte pipeline de locate (de findutils ) e grep para encontrar arquivos cujos nomes de caminho contenham duas palavras word1 e word2 , sem nenhuma ordem específica entre si:

locate -i word1 | grep -i  word2

Eu queria saber como fazer isso com um único comando não-pipeline sozinho? É uma maneira melhor do que o meu comando de pipeline?

O locate suporta algum regex no qual podemos formular meu padrão de pesquisa?

Obrigado.

A solução com find é link

    
por Tim 22.01.2018 / 13:23

1 resposta

2

Isso depende muito da sua implementação de locate . Esse não é um comando padrão e existem algumas implementações diferentes com diferenças bastante significativas.

  1. Existe uma implementação no GNU findutils.

    Com esse:

    locate -i word1 word2
    

    localiza os arquivos cujo caminho contém word1 ou word2 case insensivelmente enquanto

    locate -Ai word1 word2
    

    localiza arquivos cujo caminho contém ambos.

    Ele também suporta uma opção --regex e --regextype como para o GNU %código%. Por definição, isso é find estilo regexps, alguma forma de híbrido entre BRE e ERE.

    Com esse, você poderia fazer:

    locate -ir 'word1.*word2\|word2.*word1'
    
  2. A implementação de emacs (o padrão no Debian e derivados) também suporta mlocate . Tem -A / -r , mas não --regex e seus REs são expressões regulares básicas. Nos sistemas como os GNU cujos BREs suportam --regextype para alternação como extensão, você também pode fazer:

    locate -ir 'word1.*word2\|word2.*word1'
    
  3. o ast-open tem um script de wrapper \| , bem como um script ksh93 em torno de locate (o sucessor de tw ) . Não suporta find nem -A , mas você pode usar todo o poder dos curingas -r , então você pode usar por exemplo operadores de look-perl-like com:

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

    Ou ksh93 ksh93 glob operator:

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

    É particularmente lento em comparação com os outros, embora o padrão não está ancorado. É melhor depois de ancorar ( & eft e l ight) é restaurado com:

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

Um problema com o piping para r é que ele não funciona para o caminho do arquivo que contém caracteres de nova linha. Com o GNU locate ou mlocate, você pode usar a opção grep para usar registros delimitados por NUL que você pode usar em combinação com a opção -0 do GNU -z :

locate -i0 word1 | grep -z word2 | grep -z word3 | tr '
locate -i0 word1 | awk -v RS='
locate -i0 word1 | perl -ln0e 'print if /word2/ && /word3/'
' '/word2/ && /word3/'
' '\n'

Ou grep no GNU gawk ou no -v RS='mawk' de ThomasDickey:

locate -i word1 word2

Ou perl -ln0 :

locate -Ai word1 word2
    
por 05.06.2018 / 18:00