Você perdeu um ;(escapou aqui \;para impedir que o shell o interprete) ou um +e um {}:
find . -exec grep chrome {} \;
ou
find . -exec grep chrome {} +
findserá executado grepe substituirá {}pelos nomes de arquivo encontrados. A diferença entre ;e +é que, com ;um único grepcomando para cada arquivo, é executado, enquanto o +maior número possível de arquivos é fornecido como parâmetro de grepuma só vez.
Se você usar o \; a construção final grep é passada um arquivo de cada vez; portanto, não exibe o nome do arquivo por padrão, apenas as linhas correspondentes. Para obter uma lista de arquivos, adicione o uso grep -lsdentro da construção find.
Caleb
9
find . -exec grep foo {} +mostrará uma saída como esta./dir/file.py:from foo import bar
sg
10
find . -exec grep foo {} \;mostrará a você a saída como estafrom foo import bar
sg
9
find . -exec grep -l foo {} +mostrará a você a saída como esta./dir/file.py
sg
8
find . -exec grep -l foo {} \;mostrará a você a saída como esta./dir/file.py
sg
46
Você não precisa usar findpara isso; O grep é capaz de lidar com a abertura dos arquivos a partir de uma lista global de tudo no diretório atual:
grep chrome *
... ou até recursivamente para a pasta e tudo sob ela:
O grep engasgará se a expansão ultrapassar ARG_MAX. O -R visitará tudo enquanto estiver usando o find, é possível adicionar primitivos com mais facilidade para excluir determinados arquivos (-name, etc) ou nem mesmo visitar as subárvores (-une).
Mel
6
Bons pontos @Mel. Meu argumento era que, com toda a probabilidade, a parte solicitante estava tornando as coisas mais complexas do que o necessário, apresentando findquando greppoderia fazer o trabalho, mas, em alguns casos, seria mais eficaz usar o find para refinar a lista de arquivos antes de sair para grep.
Caleb
4
@Mel grepnão engasga nesse caso, execfaz.
26413 Chris Down
Funciona apenas no caso de todos os arquivos estarem no mesmo diretório, não quando estão espalhados por subdiretórios.
Yaba
1
@Yaba Minha resposta indica como lidar com o caso de arquivos espalhados por subdiretórios.
Caleb
18
find . | xargs grep 'chrome'
você também pode fazer:
find . | xargs grep 'chrome' -ls
O primeiro mostra as linhas nos arquivos, o segundo apenas lista os arquivos.
A opção de Caleb é mais limpa, menos pressionamentos de tecla.
O problema xargsé que ele espera que sua entrada seja citada de uma maneira peculiar que findnão produza. Portanto find … | xargs …, não funciona se você tiver nomes de arquivos que contenham espaços em branco ou \'".
Gilles
3
@ Gilles Você pode contornar esse problema usando algo como, find . | xargs -n1 -iX grep "X" 'chrome'para que os argumentos sejam alimentados um de cada vez e citados. Obviamente, essa é uma maneira terrivelmente ineficiente de lidar com este exemplo, mas para algumas situações é bom.
Caleb
Para completar, também devemos mencionar a opção -i para insensibilidade a maiúsculas e minúsculas com 'grep'. Também existe -iname em busca de insensibilidade ao caso.
Mathew
9
@ Caleb: A única maneira 100% confiável de xargslidar com os nomes de arquivos do Linux é find ... -print0 | xargs -0usando NUL como separador. Alternativa - xargs -d '\n'usando nova linha como separador, 99% de confiabilidade.
grawity
Eu uso isso frequentemente, mas falhará em listas muito longas de nomes de arquivos; nesse momento, find -exec se torna o vencedor.
Spacemoose
5
Encontrar é uma maneira e você pode tentar. the_silver_searcherTudo o que você precisa fazer é
ag chrome
Ele pesquisará o chrome em todos os arquivos (incluindo subdiretórios) e é mais rápido do que o encontrado
Há também pt (pesquisador de platina, disponível em github.com/monochromegane/the_platinum_searcher ) que, IMHO, faz o trabalho mais rapidamente - pode não importar se houver apenas alguns arquivos.
Ele procura recursivamente todos os arquivos .py e cada arquivo imprime o nome do arquivo e o fgrep para 'olá' nesse arquivo (para cada). Saída parece (apenas executou uma hoje):
não mexer com o seu fluxo de trabalho, mas você pode gostar: find . -name "*.py" -exec fgrep -l hello {} \; - que vai imprimir os nomes de arquivos que correspondem, e nada mais
find: Only one instance of {} is supported with -exec ... +
-exec
comfind
Respostas:
Você perdeu um
;
(escapou aqui\;
para impedir que o shell o interprete) ou um+
e um{}
:ou
find
será executadogrep
e substituirá{}
pelos nomes de arquivo encontrados. A diferença entre;
e+
é que, com;
um únicogrep
comando para cada arquivo, é executado, enquanto o+
maior número possível de arquivos é fornecido como parâmetro degrep
uma só vez.fonte
grep -ls
dentro da construção find.find . -exec grep foo {} +
mostrará uma saída como esta./dir/file.py:from foo import bar
find . -exec grep foo {} \;
mostrará a você a saída como estafrom foo import bar
find . -exec grep -l foo {} +
mostrará a você a saída como esta./dir/file.py
find . -exec grep -l foo {} \;
mostrará a você a saída como esta./dir/file.py
Você não precisa usar
find
para isso; O grep é capaz de lidar com a abertura dos arquivos a partir de uma lista global de tudo no diretório atual:... ou até recursivamente para a pasta e tudo sob ela:
fonte
find
quandogrep
poderia fazer o trabalho, mas, em alguns casos, seria mais eficaz usar o find para refinar a lista de arquivos antes de sair para grep.grep
não engasga nesse caso,exec
faz.você também pode fazer:
O primeiro mostra as linhas nos arquivos, o segundo apenas lista os arquivos.
A opção de Caleb é mais limpa, menos pressionamentos de tecla.
fonte
xargs
é que ele espera que sua entrada seja citada de uma maneira peculiar quefind
não produza. Portantofind … | xargs …
, não funciona se você tiver nomes de arquivos que contenham espaços em branco ou\'"
.find . | xargs -n1 -iX grep "X" 'chrome'
para que os argumentos sejam alimentados um de cada vez e citados. Obviamente, essa é uma maneira terrivelmente ineficiente de lidar com este exemplo, mas para algumas situações é bom.xargs
lidar com os nomes de arquivos do Linux éfind ... -print0 | xargs -0
usando NUL como separador. Alternativa -xargs -d '\n'
usando nova linha como separador, 99% de confiabilidade.Encontrar é uma maneira e você pode tentar.
the_silver_searcher
Tudo o que você precisa fazer éEle pesquisará o chrome em todos os arquivos (incluindo subdiretórios) e é mais rápido do que o encontrado
fonte
Para ver a lista de arquivos em vez de linhas:
ou:
fonte
Aqui está um exemplo de como eu costumo usar find / exec ...
Ele procura recursivamente todos os arquivos .py e cada arquivo imprime o nome do arquivo e o fgrep para 'olá' nesse arquivo (para cada). Saída parece (apenas executou uma hoje):
fonte
find . -name "*.py" -exec fgrep -l hello {} \;
- que vai imprimir os nomes de arquivos que correspondem, e nada mais