Como pesquisar texto em todo o sistema de arquivos?

53

Supondo que a ferramenta grep deva ser usada, gostaria de procurar a sequência de texto "800x600" em todo o sistema de arquivos.

Eu tentei:

grep -r 800x600 /

mas não funciona.

O que eu acredito que meu comando deve fazer é grep recursivamente através de todos os arquivos / pastas raiz para o texto "800x600" e listar os resultados da pesquisa.

O que estou fazendo errado?

Level1Coder
fonte
2
E por "não funciona", você quer dizer exatamente o que? Não imprime nenhuma saída, trava ou imprime muitos Permission deniederros? Você o executou como root ou como usuário normal?
alex
Estou recebendo alguma tração, antes de tudo, eu estava no diretório inicial do usuário, tentando executar o comando. Então agora eu tenho cd / out para fazer root. Em seguida, tentei o mesmo comando acima e estou recebendo muitos erros de permissão negada. Ok, então agora eu tente sudo grep -r 800x600 / e então eu começo a / proc / sysrq-trigger: Erro de entrada / saída
Level1Coder
Hmm, não sei por que não funcionaria. Você pode ignorar erros de acesso fazendo isso grep -r 800x600 / 2>/dev/null. Você também pode tentar executá-lo como root.
Totor 26/01

Respostas:

64

Normalmente, eu uso esse estilo de comando para executar grepvários arquivos:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

O que isso realmente faz é fazer uma lista de todos os arquivos no sistema e, em seguida, para cada arquivo, executar grepcom os argumentos fornecidos e o nome de cada arquivo.

O -xdevargumento diz que ele deve ignorar outros sistemas de arquivos - isso é bom para evitar sistemas de arquivos especiais, como /proc. No entanto, ele também ignorará também os sistemas de arquivos normais - portanto, se, por exemplo, sua pasta / home estiver em uma partição diferente, ela não será pesquisada - você precisaria dizer find / /home -xdev ....

-type fsignifica procurar apenas arquivos, para que diretórios, dispositivos e outros arquivos especiais sejam ignorados (ele ainda será executado novamente nos diretórios e será executado grepnos arquivos contidos - apenas não será executado grepno próprio diretório, o que não funcionaria de qualquer maneira). E a -Hopção para grepdiz para sempre imprimir o nome do arquivo em sua saída.

findaceita todos os tipos de opções para filtrar a lista de arquivos. Por exemplo, -name '*.txt'processa apenas arquivos que terminam em .txt. -size -2Msignifica arquivos menores que 2 megabytes. -mtime -5significa arquivos modificados nos últimos cinco dias. Junte-os a -a for e -o for or e use '('parênteses ')'para agrupar expressões (entre aspas para impedir que o shell as interprete). Então, por exemplo:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Dê uma olhada man findpara ver a lista completa de possíveis filtros.

Richard Downer
fonte
2
Observe que -xdevexcluirá todos os outros sistemas de arquivos, não apenas os especiais. (por exemplo, se tiver /homemontado como uma partição separada, não vai ser pesquisado.)
CJM
Eu tentei correr cada um, mas ambos retorno um erro -find: paths must precede expression: /
Level1Coder
11
Nota: Quando expressões regulares não são necessárias, 'fgrep' é significativamente mais rápido que 'grep', o que fará uma grande diferença se você estiver pesquisando uma árvore grande.
Nathan Kidd
11
Você pode evitar passar xargscom talvez melhor eficiência fazendo isso find / -xdev -type f -exec grep -H '800x600' +.
Totor 26/01
3
Não, o +sinal no final do findcomando realmente faz o mesmo xargs: gera um grepprocesso com vários argumentos.
Totor 27/01
14

Normalmente você não gostaria de pesquisar TUDO no sistema. O Linux usa nós de arquivo para tudo, então alguns "arquivos" não são coisas que você deseja pesquisar. Por exemplo, /dev/sdaé o dispositivo de bloco físico para o seu primeiro disco rígido. Você provavelmente deseja pesquisar os sistemas de arquivos montados, não o dispositivo de disco bruto. Também existe o /dev/randomque cospe dados aleatórios toda vez que você os lê. Pesquisa que não faz muito sentido. O /procsistema de arquivos também é problemático no seu caso.

Eu recomendaria uma de duas coisas.

  1. Não pesquise na raiz, pesquise apenas os locais que podem ser úteis. Pesquise /homeou /usrou /etcseparadamente. As informações que você está procurando provavelmente são de um tipo específico, portanto, provavelmente estarão em uma pasta específica. As definições de configuração deve estar em /etc. Seus arquivos de dados pessoais deve ser em /home. Limitar a pesquisa a uma área importante como essa reduzirá bastante os problemas com greps recursivos.

  2. Exclua o uso de áreas problemáticas --exclude-dire um conjunto de coisas que você sabe que não precisa:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Por fim, não é incomum encontrar alguns erros de 'permissão negada' ao executar um grande grep recursivo. No curso normal de uso, existem arquivos que seu usuário pode não conseguir ler. Contanto que sejam apenas alguns arquivos estranhos e não coisas como o dispositivo bruto para seus discos rígidos ou todo o sistema de arquivos proc, não há problema em ignorar os erros. Na verdade, você pode fazer isso na linha de comando enviando todos os erros para a terra nunca:

grep -r search_string /path 2> /dev/null
Caleb
fonte
3
-Iexcluir binário
Rahul Patil 31/03
2

Para simplificar, eu sugeriria o ack-grep . O link mostra muitos casos quando ack-grepé uma opção melhor.

Para usar é, após a instalação:

ack-grep pattern /
bbaja42
fonte
Obrigado por recomendar isso, mas eu executei isso e ele realmente não me deu os resultados de pesquisa que eu esperava. Parece que vou precisar ajustar muitas configurações para conseguir o que quero. A partir de agora, a resposta de Richard funciona imediatamente. Irá analisar isso no futuro, pois parece útil também.
Level1Coder
1

Outra maneira de ver é desta maneira:

grep -r /* | grep "800x600"
maniat1k
fonte
0

* então recebo um / proc / sysrq-trigger: erro de entrada / saída

Seu comando está funcionando. Você está recebendo este erro porque está tentando verificar os processos em execução em busca de uma sequência.

Eu recomendo excluir diretórios do sistema com

grep -exclude-dir = {proc, sys} "800x600" /

Koffee
fonte
-3

simplesmente

grep -r "800x600" /

-O que está errado no seu comando atual são as aspas, "". Sempre coloque o argumento da string grepentre aspas.

Amita
fonte
3
Este não é o problema aqui. Você não precisa de aspas ao fornecer esse tipo específico de argumento grep. Experimente e você verá. Coloque a string "800x600" em um arquivo grep 800x600 filee você verá que ela funciona muito bem. Obviamente, o OP está tendo outro problema.
Slm