Como combinar find e grep para uma pesquisa complexa? (GNU / linux, encontre, grep)


17

Estou tentando fazer uma pesquisa de texto em alguns arquivos que compartilham uma estrutura de diretório semelhante, mas não estão na mesma árvore de diretório, no GNU / Linux.

Eu tenho um servidor web com muitos sites que compartilham a mesma estrutura em árvore (estrutura PHP do Code Igniter MVC), então quero pesquisar em um diretório específico na árvore para cada site, por exemplo:

/srv/www/*/htdocs/system/application/

Onde * é o nome do site. E a partir desses diretórios de aplicativos , eu quero procurar em toda a árvore até as folhas, um arquivo * .php que tenha algum padrão de texto, digamos "debug (", nenhuma expressão regular é necessária.

Eu sei usar find e grep, mas não sou bom em combiná-los.

Como eu faria isso?
Desde já, obrigado!

Respostas:


19

Experimentar

find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep "debug (" {} \; -print

Isso deve procurar recursivamente nas pastas em applicationbusca de arquivos com .phpextensão e passá-los para grep.

Uma otimização para isso seria executar:

find /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep -H "debug ("

Isso usa xargspara passar todos os .phparquivos gerados findcomo argumentos para um único grepcomando; por exemplo ,. A opção e a opção de garantir que os espaços nos nomes de arquivos e diretórios sejam manipulados corretamente. A opção passada para garante que o nome do arquivo seja impresso em todas as situações. (Por padrão, imprime o nome do arquivo somente quando vários argumentos são passados.)grep "debug (" file1 file2 file3-print0find-0xargs-Hgrepgrep

De man xargs:

-0

      Os itens de entrada são finalizados por um caractere nulo em vez de espaço em branco, e as aspas e a barra invertida não são especiais (todos os caracteres são literalmente). Desativa o final da sequência de arquivos, que é tratada como qualquer outro argumento. Útil quando itens de entrada podem conter espaço em branco, aspas ou barras invertidas. A -print0opção de localização GNU produz entrada adequada para este modo.


1
+1. Isso executará grep para cada arquivo php. Se houver muitos arquivos, você poderá otimizar ainda mais porfind /srv/www/*/htdocs/system/application/ -name "*.php" -print0 | xargs -0 grep "debug ("
Jukka Matilainen 24/09/09

@jackem Concordou. Vou atualizar minha resposta de acordo.
nagul

2
Outra pequena melhoria: o xargs pode passar apenas um nome de arquivo para grep; nesse caso, o grep não mostrará o nome do arquivo se houver uma correspondência. Você pode adicionar -H ao comando grep para forçá-lo a mostrar o nome do arquivo.
Randy Orrison 24/09/09

@ Randy Esse é um ponto muito válido.
nagul

3
Essa é uma verdadeira necromancia, mas GNU findpode ser necessário que o +operador \;execute o mesmo tipo de execução de processo único que o xargsfaz. Assim, find /srv/www/*/htdocs/system/application/ -name "*.php" -exec grep -H "debug (" {} +faz o mesmo que o xargsexemplo nesta resposta, mas com menos uma bifurcação de processo (e ainda o risco de 0 para problemas de nome de arquivo).
Daniel Andersson

10

findnem mesmo é necessário para este exemplo, é possível usar grepdiretamente (pelo menos GNU grep):

grep -RH --include='*.php' "debug (" /srv/www/*/htdocs/system/application/

e estamos limitados a um único garfo de processo.

Opções:

  • -R, --dereference-recursive Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
  • -H, --with-filename Print the file name for each match. This is the default when there is more than one file to search.
  • --include=GLOB Search only files whose base name matches GLOB (using wildcard matching as described under --exclude).
  • --exclude=GLOB Skip any command-line file with a name suffix that matches the pattern GLOB, using wildcard matching; a name suffix is either the whole name, or any suffix starting after a / and before a +non-/. When searching recursively, skip any subfile whose base name matches GLOB; the base name is the part after the last /. A pattern can use *, ?, and [...] as wildcards, and \ to quote a wildcard or backslash character literally.

Apenas por curiosidade, o que as -RHopções significam?
Gus

@ Gus: Adicionado man greptrecho das descrições das opções na postagem.
Daniel Andersson

0

Seu shell pode encontrar os arquivos php e entregá-los ao grep. Na festança:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.