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

15

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órios, no GNU / Linux.

Eu tenho um servidor web com muitos sites que compartilham a mesma estrutura de árvore (framework Code Igniter MVC PHP), então eu 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 desses diretórios application , eu quero pesquisar toda a árvore até suas folhas, para um arquivo * .php que tenha algum padrão de texto dentro, digamos "debug (", nenhuma expressão regular necessária.

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

Como eu faria isso?
Obrigado antecipadamente!

    
por Petruza 24.09.2009 / 15:08

3 respostas

18

Tente

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

Isso deve pesquisar recursivamente as pastas em application para arquivos com extensão .php e passá-las para grep .

Uma otimização seria executar:

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

Isso usa xargs para passar todos os arquivos .php gerados por find como argumentos para um único comando grep ; por exemplo, grep "debug (" file1 file2 file3 . A opção -print0 da opção find e -0 de xargs garante que os espaços nos nomes de arquivos e diretórios sejam tratados corretamente. A opção -H passada para grep garante que o nome do arquivo seja impresso em todas as situações. (Por padrão, grep imprime o nome do arquivo apenas quando vários argumentos são passados.)

De man xargs:

-0

      Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally).  Disables the end of file string, which is treated like any other argument.  Useful when input items might contain white space, quote marks, or backslashes.  The GNU find -print0 option produces input suitable for this mode.
    
por 24.09.2009 / 15:25
9

find nem é necessário para este exemplo, pode-se usar grep diretamente (pelo menos GNU grep ):

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

e estamos reduzidos a um único 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.
por 10.05.2012 / 15:38
0

Seu shell pode encontrar os arquivos php e fornecê-los ao grep. No bash:

shopt -s nullglob globstar
grep searchterm /srv/www/*/htdocs/system/application/**/*.php
    
por 22.12.2016 / 21:24