Como posso grep os resultados do FIND usando -EXEC e ainda gerar um arquivo?


64

Melhor explicar em exemplos.

Eu posso:

find . -name "*.py" -type f > output.txt

Mas como posso armazenar a saída no mesmo arquivo para:

find . -name "*.py" -type f -exec grep "something" {} \

Não posso simplesmente fazer

find . -name "*.py" -type f -exec grep "something" {} \ > output.txt

Respostas:


106

Se eu entendi direito, é isso que você quer fazer:

find . -name '*.py' -print0 | xargs -0 grep 'something' > output.txt

Findtodos os arquivos com extensão py, grepapenas linhas que contêm somethinge salvam as linhas output.txt. Se o arquivo contiver algo, ele será substituído.

Editar: Usando -exec:

find . -name '*.py' -exec grep 'something' {} \; > output.txt

Estou incorporando o comentário de Chris Downs aqui. O comando acima resultará na grepexecução quantas vezes forem findencontradas as ocorrências. No entanto, se você substituir o ;por a +, grepserá chamado com a saída findconcatenada (até um determinado limite). Veja a pergunta Usando ponto-e-vírgula (;) vs mais (+) com exec para encontrar mais informações sobre o assunto.


16
Use em +vez de \;, ele melhorará significativamente o tempo de execução (uma vez que contatenará os argumentos anteriores à execução até ARG_MAX).
— Chris Baixo

Agora eu entendo o poder dos xargs! Obrigado!
— domih

4
Use grep -Hse você deseja incluir o nome do arquivo do arquivo na saída.
— 23318 Steinar

18

Se você quiser salvar todas as linhas correspondentes em todos os arquivos output.txt, seu último comando funcionará, exceto que você está perdendo o necessário ;no final do comando.

find . -name "*.py" -type f -exec grep "something" {} \; > output.txt

Se você deseja que cada execução grepproduza saída para um arquivo diferente, execute um shell para calcular o nome do arquivo de saída e executar o redirecionamento.

find . -name "*.py" -type f -exec sh -c 'grep "something" <"$0" >"$0.txt"' {} \;

o último muito legal: D
— bakytn 20/09/11

Para expandir a resposta do @gilles e torná-la um pouco mais informativa, especialmente se a lista de arquivos com os quais você está lidando for grande, você pode relatar o nome do arquivo (caminho relativo) de cada arquivo, juntamente com os resultados em grep'ed usando este : find . -name "*.py" -type f -exec grep "something" {} \; -print > output.txt E se você gostaria de ver os números das linhas grep'ed, você pode, é claro, usargrep -n "something"
— JJMpls

9

Para o registro, greptem --includee --excludeargumentos que você pode usar para filtrar os arquivos pesquisados:

grep -r --include="*.py" "something" > output.txt

2
Pelo menos o GNU grepfaz.
— Phk # 1/16

2

Use tee:

find . -name '*.py' | tee output.txt | xargs grep 'something'

A ressalva, é se você tiver quaisquer arquivos com caracteres especiais (incluindo espaços), que xargse grepnão vai funcionar bem com ( a file.txtserá interpretada como dois arquivos, ae file.txt). A alternativa é usar o -xou -print0, mas qualquer um deles poluirá o seu output.txt. O -xirá usar \para escapar de certos caracteres especiais e isso será exibido output.txt. Ele -print0usará um byte nulo como separador de campos (que também requer xargs -0) e output.txtserá semelhante a uma longa linha de texto contígua.

Como você lida (ou não) com isso depende de você.

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.