Localizando arquivos que contêm uma determinada string usando find (1) e grep (1)


70

find . -type f -print -exec cat {} \; | grep some string

O comando acima não imprime o caminho do arquivo.

Eu estou usando: Ubuntu, bash 4.


Talvez ele não atenda aos resultados esperados devido ao filtro grep. E quanto a isto:find . -type f -fprint /dev/stderr -exec cat {} \; | grep some string
artistoex

Qual é o objetivo que você deseja alcançar? Na saída você está recebendo seqüências de caracteres grepped de arquivos, deseja o caminho desses arquivos?
Mirkobrankovic

Sim, quero imprimir o caminho dos arquivos que contêm a string 'some string'. A sugestão @artistoex imprime todos os caminhos de arquivo.
H.Rabiee

Você pode simplesmente usar o ackgrep em todos os arquivos no diretório atual, possivelmente filtrando apenas em certos tipos de arquivo.
Jaap Ancianidade

Respostas:


87

Isso grepocorre porque você está alimentando um fluxo de texto que, por acaso, contém nomes de arquivos. Como você não forneceu nomes de arquivos como argumentos para grep, não se pode esperar deduzir de que arquivo veio uma linha correspondente. Use xargs:

find . -type f -print | xargs grep "some string"

Como você possui o GNU find / xargs, esta é uma maneira mais segura de o xargs ler os nomes de arquivos:

find . -type f -print0 | xargs -0 grep "some string"

Se você deseja apenas os nomes de arquivos que têm uma linha correspondente sem mostrar a linha correspondente:

find . -type f -print0 | xargs -0 grep -l "some string"

Como eu combinaria os comandos acima com pesquisar e substituir? Como, grep então sed?
CMCDragonkai

11
a descoberta | nomes de dutos grep saídas, então:sed '...' $(find ... | xargs grep -l ...)
Glenn Jackman

107

eu uso

grep "some string" . -R

e trabalhando mais rápido

ps

Caso de uso mais complexo

grep -HiRE "some string|other string" . #H for file printing, i for case-insensitive, R for recursive search, E for regex 

Para ler a explicação do parâmetro i

grep --help | grep -- -i

17
E -nse você quiser números de linha. +1 para resposta simplificada.
Chad Skeeters

@ChadSkeeters exatamente. O uso da descoberta não fornece essa solução.
ArcherGodson

11
Isso deve ser marcado como a resposta correta, para ser honesto. O atualmente selecionado detalha algo completamente diferente.

12

Frequentemente procuro o código-fonte em estruturas de pastas complexas e acho útil usar:

cd /your/folder/
grep -rHino "your string"

Com esses parâmetros, sem usar find , obtenho o caminho completo do arquivo e o número da linha que contém a sequência especificada .

Também é fácil lembrar, porque o BASH é através da sua pesquisa como um rHino :)

Vou mostrar como isso funciona com um exemplo rápido.

Vamos exibir o conteúdo de um arquivo usando cat:

jeeves ~ # cat fw.stop
#!/bin/sh
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

E vamos procurar recursivamente todos os arquivos que contêm a string "iptables -P":

jeeves ~ # grep -rinHo "iptables -P"
fw.stop:9:iptables -P
fw.stop:10:iptables -P
fw.stop:11:iptables -P

Como você pode ver na saída, temos o nome do arquivo: hit row: search string

Aqui está uma descrição mais detalhada dos parâmetros usados:

-r Para cada operando de diretório, leia e processe todos os arquivos nesse diretório, recursivamente. Siga os links simbólicos na linha de comando, mas pule os links simbólicos encontrados recursivamente. Observe que, se nenhum operando de arquivo for fornecido, o grep pesquisará o diretório de trabalho. É o mesmo que a opção '--directories = recurse'.

-i Imprime o nome do arquivo para cada correspondência. Esse é o padrão quando há mais de um arquivo para pesquisar.

-n Prefixa cada linha de saída com o número da linha com base em 1 em seu arquivo de entrada. (-n é especificado pelo POSIX.)

-H Imprime o nome do arquivo para cada correspondência. Esse é o padrão quando há mais de um arquivo para pesquisar.

-o Imprima apenas as partes correspondentes (não vazias) das linhas correspondentes, com cada uma dessas partes em uma linha de saída separada. As linhas de saída usam os mesmos delimitadores da entrada e os delimitadores são bytes nulos se -z (--null-data) também for usado (consulte Outras opções).


2

eu preferi

| encontre o arquivo | faça grep ont encontrando arquivo | mostre o caminho completo do arquivo

encontre / -type f -exec grep 'alguma string' {} \; -exec echo {} \;


0

O Silver Searcher é um utilitário muito rápido e útil para pesquisar arquivos e conteúdo.

Para resolver seu problema, o comando silver searcher ficaria assim ...

ag 'some string' -l

-l Imprimir apenas nomes de arquivos que contenham correspondências (não imprima as linhas correspondentes)

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.