Encontre arquivos que contenham um determinado texto

153

No bash, quero retornar o nome do arquivo (e o caminho para o arquivo) para cada arquivo do tipo que .php|.html|.jscontém a sequência que não diferencia maiúsculas de minúsculas"document.cookie" | "setcookie"

Como eu faria isso?

Owen
fonte
4
Você já pensou em usar o grep? cyberciti.biz/faq/grep-in-bash
Terrance
Este título é bastante enganador. "find-files-contendo-um-dado-texto"
Josh C

Respostas:

212
egrep -ir --include=*.{php,html,js} "(document.cookie|setcookie)" .

O rsinalizador significa pesquisar recursivamente (pesquisar subdiretórios). A ibandeira significa que não diferencia maiúsculas de minúsculas.

Se você deseja apenas nomes de arquivos, adicione o sinalizador l(minúsculo L):

egrep -lir --include=*.{php,html,js} "(document.cookie|setcookie)" .
bear24rw
fonte
que não pareceu funcionar para mim (pelo menos não no mac) .... simplesmente trava ... egrep -lir --include = * "repo" egrep: aviso: pesquisa recursiva de stdin
Dean Hiller
13
Você esqueceu de adicionar o caminho a pesquisar. O caminho é '.' no exemplo acima. No seu caso, o script está aguardando a entrada pesquisar no stdin. Tente: egrep -lir --include = * "repo" / (ou qualquer outro caminho)
LodeRunner
1
grep -E ... >egrep ...
Aman
Erro grep: (error|fail): No such file or directoryno Ubuntu Desktop 16; alguma dica?
Nam G VU
Para fazer isso funcionar, tive que pular o * com \. então eu tenho--include=\*.{php,html,js}
Mehrad Mahmoudian
53

Tente algo como grep -r -n -i --include="*.html *.php *.js" searchstrinhere .

o -itorna caso insensível

o .com os meios finais você deseja começar a partir de seu diretório atual, isso poderia ser substituído por qualquer diretório.

os -rmeios fazem isso recursivamente, na árvore de diretórios

o -nimprime o número da linha para correspondências.

o --includepermite adicionar nomes de arquivos, extensões. Curingas aceitos

Para mais informações, consulte: http://www.gnu.org/software/grep/

Raoul
fonte
4
Ou talvez usar a -lopção (apenas imprimir nomes de arquivos que jogo) em vez de-n
glenn jackman
15

findeles e greppara a string:

Ele encontrará todos os arquivos dos seus três tipos em / initial / path e grep para a expressão regular '(document\.cookie|setcookie)'. Divida mais de 2 linhas com a barra invertida apenas para facilitar a leitura ...

find /starting/path -type f -name "*.php" -o -name "*.html" -o -name "*.js" | \
 xargs egrep -i '(document\.cookie|setcookie)'
Michael Berkowski
fonte
1
Como o uso universal da descoberta, mas a minha mente melhor usar-exec grep -l 'sth' {} \;
NGix
Obrigado @ Michael Berkowski Desta maneira, mais rápido mais de 5 ou 8 vezes # egrep -ir --include=file.foo "(foo|bar)" /dirno diretório de ~ 500Gb de peso.
Qh0stM4N
9

Parece um trabalho perfeito para grepou talvez ack

Ou esta maravilhosa construção:

find . -type f \( -name *.php -o -name *.html -o -name *.js \) -exec grep "document.cookie\|setcookie" /dev/null {} \;
Fredrik Pihl
fonte
O uso de +1 -exec grep...é melhor que o meu xargsmétodo, pois não engasga com espaços nos nomes de arquivos.
Michael Berkowski 27/05
@MichaelBerkowski: Você pode usá-lo como este para lidar com espaços em branco em nomes de arquivos: find . -type f -print0 | xargs -0 -I {} grep "search_string" {}. Obviamente, as outras opções também podem ser adicionadas.
Pascal
4
find . -type f -name '*php' -o -name '*js' -o -name '*html' |\
xargs grep -liE 'document\.cookie|setcookie'
n
fonte
3

Apenas para incluir mais uma alternativa, você também pode usar isto:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \;

Onde:

  • -regextype posix-extendeddiz findque tipo de regex esperar
  • -regex "^.*\.(php|html|js)$"informa findao próprio regex que os nomes de arquivos devem corresponder
  • -exec grep -EH '(document\.cookie|setcookie)' {} \;diz findpara executar o comando (com suas opções e argumentos) especificado entre a -execopção e o \;de cada arquivo encontrado, onde {}representa onde o caminho do arquivo está nesse comando.

    enquanto

    • Eopção diz greppara usar regex estendido (para apoiar os parênteses) e ...
    • Hopção diz greppara imprimir caminhos de arquivo antes das correspondências.

E, dado isso, se você quiser apenas caminhos de arquivo, poderá usar:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \; | sed -r 's/(^.*):.*$/\1/' | sort -u

Onde

  • |[pipe] envia a saída de findpara o próximo comando depois disso (que é sed, então sort)
  • ropção diz sedpara usar regex estendido.
  • s/HI/BYE/diz sedpara substituir toda Primeira ocorrência (por linha) de "HI" por "BYE" e ...
  • s/(^.*):.*$/\1/diz para substituir o regex (^.*):.*$(ou seja, um grupo [incluído entre ()] incluindo tudo [ .*= um ou mais caracteres] desde o início da linha [ ^] até 'o primeiro': 'seguido de qualquer coisa até' o final de linha [ $]) pelo primeiro grupo [ \1] do regex substituído.
  • udiz a classificação para remover entradas duplicadas (use sort -ucomo opcional).

... Longe de ser a maneira mais elegante. Como eu disse, minha intenção é aumentar o leque de possibilidades (e também dar explicações mais completas sobre algumas ferramentas que você pode usar).

Pedro Vernetti
fonte