Como usar o comando “grep” para encontrar texto incluindo subdiretórios

334

Eu quero encontrar todos os arquivos que contenham uma string específica de texto. O comando grep funciona, mas não sei como usá-lo para todos os diretórios (só posso fazer isso para meu diretório atual). Eu tentei ler man grep , mas não deu nenhuma ajuda.

    
por Smile.Hunter 01.08.2011 / 13:38

11 respostas

429

Seria melhor usar

grep -rl "string" /path

onde

  • A opção -r (ou --recursive ) é usada para percorrer também todos os subdiretórios de /path , enquanto
  • A opção -l (ou --files-with-matches ) é usada para imprimir apenas nomes de arquivos correspondentes e não as linhas correspondentes (isso também pode melhorar a velocidade, já que grep pára de ler um arquivo na primeira correspondência com essa opção).
por enzotib 01.08.2011 / 13:55
155

Se você estiver procurando por linhas correspondentes em arquivos, meu comando favorito é:

grep -Hrn 'search term' path/to/files
  • -H faz com que o nome do arquivo seja impresso (implícito quando vários arquivos são pesquisados)
  • -r faz uma pesquisa recursiva
  • -n faz com que o número da linha seja impresso

path/to/files pode ser . para pesquisar no diretório atual

Outras opções que considero muito úteis:

  • -I ignora arquivos binários (complemento: -a trata todos os arquivos como texto)
  • -F treat search term como um literal, não uma expressão regular
  • -i faz uma pesquisa sem distinção entre maiúsculas e minúsculas
  • --color=always para forçar as cores mesmo quando estiver percorrendo less . Para fazer less suportar cores, você precisa usar a opção -r :

    grep -Hrn search . | less -r
    
  • --exclude-dir=dir útil para excluir diretórios como .svn e .git .

    
por Lekensteyn 01.08.2011 / 14:27
23

Eu acredito que você pode usar algo assim:

find /path -type f -exec grep -l "string" {} \;

Explicação dos comentários

find é um comando que permite localizar arquivos e outros objetos, como diretórios e links em subdiretórios de um determinado caminho. Se você não especificar uma máscara que os nomes de arquivos devem atender, ele enumera todos os objetos de diretório.

  • -type f especifica que deve processar apenas arquivos, não diretórios, etc.
  • -exec grep especifica que para cada arquivo encontrado, ele deve executar o comando grep, passando seu nome de arquivo como um argumento para ele, substituindo {} pelo nome do arquivo
por dmityugov 01.08.2011 / 13:48
18

Meu comando padrão é

grep -Rin string *

Eu uso um capitólio 'R' porque ls o usa como recursivo. Como o grep aceita ambos, não há razão para não usá-lo.

EDIT: por HVNSweeting, aparentemente -R seguirá links simbólicos onde -r não irá.

    
por user606723 01.08.2011 / 16:43
11

Se você estiver disposto a experimentar algo novo, faça uma ack uma chance. O comando para pesquisar recursivamente o diretório atual para string é:

ack string

A instalação é bem simples:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(Desde que você já tenha o diretório ~/bin e, de preferência, esteja no seu PATH .)

    
por Konrad Rudolph 01.08.2011 / 17:09
3

O comando rgrep é dedicado para tal necessidade

Se não estiver disponível, você pode obtê-lo assim

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

Você pode definir diretamente em suas opções grep padrão, conforme descrito acima.

Eu pessoalmente uso

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

tópico relacionado: como usar sempre o rgrep com a cor

    
por mnono 02.01.2015 / 14:58
2

Atualização 2:

Esta linha de comandos que usam find e grep corrige o problema:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> para saída colorida:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

Exemplo:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

Um exemplo executado no instantâneo abaixo:

Atualização1:

Vocêpodetentarseguirocódigo;comoumafunçãoemseu.bashrcou.bash_aliasesouemumscript:

wherein(){foriin$(find"$1" -type f 2> /dev/null);
    do
        if grep --color=auto -i "$2" "$i" 2> /dev/null; then
            echo -e "3[0;32mFound in: $i 3[0m\n";
        fi;
    done
}

Uso: wherein /path/to/search/in/ searchkeyword

exemplo:

$ wherein ~/Documents/ "hello world"

(Nota: Como sugerido nos comentários abaixo por @enzotib, isso não funciona com arquivos / diretórios incluindo espaços em seus nomes.)

postagem original

Para pesquisar a string e exibir apenas essa linha com a string de pesquisa:

$ for i in $(find /path/of/target/directory -type f); do \
    grep -i "the string to look for" "$i"; done

por exemplo:

$ for i in $(find /usr/share/applications -type f); \
    do grep -i "web browser" "$i"; done

Para exibir o nome do arquivo que contém a string de pesquisa:

$ for i in $(find /path/of/target/directory -type f); do \
    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

por exemplo:

$ for i in $(find /usr/share/applications -type f); \
    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
    fi; done;
    
por precise 25.01.2014 / 12:11
1

Eu faço isso usando xargs, um comando muito subestimado

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./ fornece uma lista recursiva de todos os arquivos em uma pasta atual então você canaliza para xargs que executa o comando grep em cada um desses arquivos

    
por deadprogrammer 01.08.2011 / 17:30
1

grep ( GNU ou BSD )

Você pode usar a ferramenta grep para pesquisar recursivamente a pasta atual com o parâmetro -r , como:

grep -r "pattern" .

Nota: -r - Pesquise recursivamente subdiretórios.

Para pesquisar em arquivos específicos, você pode usar uma sintaxe globbing como:

grep "class foo" **/*.c

Observação: usando a opção de globbing ( ** ), ele verifica todos os arquivos recursivamente com extensão ou padrão específico. Para ativar esta sintaxe, execute: shopt -s globstar . Você também pode usar **/*.* para todos os arquivos (excluindo ocultos e sem extensão) ou qualquer outro padrão.

Se você tiver o erro de que seu argumento é muito longo, considere restringir sua pesquisa ou use a sintaxe find como:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

Como alternativa, use ripgrep .

ripgrep

Se você estiver trabalhando em projetos maiores ou em arquivos grandes, use ripgrep , como:

rg "pattern" .

Faça check-out dos documentos, etapas de instalação ou código-fonte na página do projeto do GitHub .

É muito mais rápido que qualquer outra ferramenta como o GNU / BSD grep , ucg , ag , sift , ack , pt ou similar, já que é construído em cima de regex de Rust engine que usa autômatos finitos, SIMD e otimizações literais agressivas para tornar a pesquisa muito rápida.

Ele suporta padrões de ignorados especificados em .gitignore arquivos, portanto, um único caminho de arquivo pode ser comparado a vários padrões globais simultaneamente.

Você pode usar os parâmetros comuns, como:

  • -i - pesquisa insensível.
  • -I - Ignora os arquivos binários.
  • -w - Pesquise as palavras inteiras (ao contrário da correspondência parcial de palavras).
  • -n - Mostra a linha do seu jogo.
  • -C / --context (por exemplo, -C5 ) - Aumenta o contexto, então você vê o código ao redor.
  • --color=auto - Marque o texto correspondente.
  • -H - Exibe o nome do arquivo onde o texto é encontrado.
  • -c - Exibe a contagem de linhas correspondentes. Pode ser combinado com -H .
por kenorb 11.04.2018 / 13:21
0

Eu sei que há muitas respostas aqui, mas aqui está uma alternativa se você quiser adicionar outras restrições ao pesquisar os arquivos:

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

Isso funciona porque grep retornará 0 se encontrar um resultado, 1 caso contrário. Por exemplo, você pode encontrar arquivos de 1 MB grandes e contendo algo:

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

Para vários requisitos, você provavelmente desejará usar o sinalizador do otimizador -O que existe no grep do GNU.

    
por Ztyx 11.03.2015 / 14:56
0

Um script (find-in-code) para pesquisar em C, código CPP:

#!/bin/sh

find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"

Uso:

find-in-code "search string"
    
por nvd 11.06.2015 / 18:49