Estou fazendo um finde, em seguida, obtendo uma lista de arquivos. Como canalizá-lo para outro utilitário como cat(para que o gato exiba o conteúdo de todos esses arquivos) e basicamente precise de grepalgo desses arquivos.
Estou fazendo um finde, em seguida, obtendo uma lista de arquivos. Como canalizá-lo para outro utilitário como cat(para que o gato exiba o conteúdo de todos esses arquivos) e basicamente precise de grepalgo desses arquivos.
Respostas:
Canalização para outro processo (embora isso NÃO realize o que você disse que está tentando fazer):
command1 | command2
Isso enviará a saída do comando1 como a entrada do comando2
-execem um find(isso fará o que você deseja fazer - mas é específico find)
find . -name '*.foo' -exec cat {} \;
(Tudo entre finde -execos predicados de localização que você já estava usando. {}Substituirá o arquivo específico que você encontrou no comando ( cat {}nesse caso); \;é para finalizar o -execcomando.)
envia a saída de um processo como argumentos de linha de comando para outro processo
command2 `command1`
por exemplo:
cat `find . -name '*.foo' -print`
(Observe que estas não são aspas regulares (sob o til ~ do meu teclado).) Isso enviará a saída de command1para command2argumentos de linha de comando. Observe que os nomes de arquivos que contêm espaços (novas linhas, etc) serão divididos em argumentos separados.
findpermitem escrever:, find . -name '*.foo' -exec cat {} +onde +indica que finddeve agrupar quantos nomes de arquivos forem convenientes em uma única chamada de comando. Isso é bastante útil (lida com espaços etc. nos nomes de arquivos sem recorrer a -print0e xargs -0).
find . -name '*.foo' | xargs cat
find . -name '*.foo' | xargs cat | grep string
O POSIX 2008 adicionou o +marcador, o findque significa que agora agrupa automaticamente quantos arquivos forem razoáveis em uma única execução de comando, muito parecido com o xargsfaz, mas com várias vantagens:
O problema do nome do arquivo é um problema xargssem a -0opção e o problema 'executar mesmo com zero nome de arquivo' é um problema com ou sem a -0opção - mas o GNU xargstem a opção -rou --no-run-if-emptypara impedir que isso aconteça. Além disso, essa notação reduz o número de processos, não é provável que você avalie a diferença de desempenho. Portanto, você poderia escrever sensatamente:
find . -exec grep something {} +
find . -print | xargs grep something
Se você estiver no Linux ou tiver o GNU finde os xargscomandos, use -print0com finde -0com xargspara manipular nomes de arquivos que contenham espaços e outros caracteres estranhos.
find . -print0 | xargs -0 grep something
grepSe você não quiser os nomes dos arquivos (apenas o texto), adicione uma opção apropriada para grep(geralmente -hpara suprimir 'títulos'). Para garantir absolutamente que o nome do arquivo seja impresso grep(mesmo que apenas um arquivo seja encontrado ou a última chamada de greptenha apenas um nome de arquivo), adicione /dev/null-o à xargslinha de comando, para que sempre haja pelo menos dois nomes de arquivo.
xargs grep something.
findé canalizada para a entrada padrão de xargs. O xargsprograma lê sua entrada padrão, dividindo a entrada em espaço em branco (espaços em branco, novas linhas, guias, etc) e anexa várias palavras ao comando grep somethinge executa a linha de comando. xargsem seguida, continua lendo a entrada e executando comandos até ficar sem entrada. xargsexecuta o grepcomando quantas vezes for necessário para a entrada que é fornecida ( findneste exemplo).
/dev/nullperde as mensagens de erro.
Existem algumas maneiras de passar a lista de arquivos retornados pelo findcomando para o catcomando, embora tecnicamente nem todos usem canalização, e nenhum deles seja canalizado diretamente cat.
O mais simples é usar backticks ( `):
cat `find [whatever]`
Isso pega a saída finde efetivamente a coloca na linha de comando de cat. Isso não funciona bem se findhouver muita saída (mais do que pode caber em uma linha de comando) ou se a saída tiver caracteres especiais (como espaços).
Em algumas conchas, inclusive bash, pode-se usar em $()vez de reticulares:
cat $(find [whatever])
Isso é menos portátil, mas é aninhado. Além disso, tem praticamente as mesmas ressalvas que os backticks.
Como a execução de outros comandos no que foi encontrado é de uso comum find, o find possui uma -execação que executa um comando para cada arquivo encontrado:
find [whatever] -exec cat {} \;
O {}é um espaço reservado para o nome do arquivo e \;marca o final do comando (é possível executar outras ações depois -exec.)
Isso será executado catuma vez para cada arquivo, em vez de executar uma única instância, cattransmitindo vários nomes de arquivos que podem ser ineficientes e podem não ter o comportamento desejado para alguns comandos (embora seja bom cat). A sintaxe também é difícil de digitar - você precisa escapar do ponto e vírgula porque o ponto e vírgula é especial para o shell!
Algumas versões find(principalmente a versão GNU) permitem substituir ;por+ a utilização -execdo modo de acréscimo para correr menos casos de cat:
find [whatever] -exec cat {} +
Isso passará vários nomes de arquivos para cada chamada de cat, o que pode ser mais eficiente.
Observe que isso não garante que você use uma única chamada, no entanto. Se a linha de comando for muito longa, os argumentos serão espalhados por várias invocações decat . Pois catisso provavelmente não é grande coisa, mas para alguns outros comandos isso pode mudar o comportamento de maneiras indesejáveis. Nos sistemas Linux, o limite de comprimento da linha de comando é bastante grande, portanto, a divisão em várias invocações é bastante rara em comparação com outros sistemas operacionais.
A abordagem clássica / portátil é usar xargs:
find [whatever] | xargs cat
xargsexecuta o comando especificado ( catneste caso) e adiciona argumentos com base no que lê do stdin. Assim como -execcom +, isso vai quebrar a linha de comando, se necessário. Ou seja, se findproduzir muita saída, ele será executado catvárias vezes. Conforme mencionado na seção -execanterior, existem alguns comandos em que essa divisão pode resultar em um comportamento diferente. Observe que usarxargs dessa maneira apresenta problemas com espaços nos nomes de arquivos, pois xargsapenas usa espaços em branco como delimitador.
O método mais robusto, portátil e eficiente também usa xargs :
find [whatever] -print0 | xargs -0 cat
O -print0sinalizador indica findpara usar \0delimitadores (caracteres nulos) entre os nomes de arquivos, e o -0sinalizador informa xargspara esperar esses \0delimitadores. Isso tem um comportamento praticamente idêntico ao da abordagem -exec... +, embora seja mais portátil (mas infelizmente mais detalhado).
ls.
$()Também funciona com comandos diferentes de find .
Parece um trabalho para um script de shell para mim:
for file in 'find -name *.xml'
do
grep 'hello' file
done
ou algo assim
O comando find possui um argumento -exec que você pode usar para coisas como essa; você pode fazer o grep diretamente usando isso.
Por exemplo ( daqui, outros bons exemplos nesta página ):
find . -exec grep "www.athabasca" '{}' \; -print
No bash, o seguinte seria apropriado:
find /dir -type f -print0 | xargs -0i cat {} | grep whatever
Isso localizará todos os arquivos no /dirdiretório e canalizará com segurança os nomes de arquivos xargs, os quais serão conduzidos com segurança grep.
Ignorar xargsnão é uma boa ideia se você tiver muitos milhares de arquivos /dir; catserá interrompido devido ao tamanho excessivo da lista de argumentos. xargsvai resolver tudo isso para você.
O -print0argumento findmescla com o -0argumento xargspara manipular nomes de arquivos com espaços corretamente. O -iargumento para xargspermite inserir o nome do arquivo quando necessário na catlinha de comando. Os colchetes são substituídos pelo nome do arquivo canalizado no catcomando de find.
Isso funciona para mim
find _CACHE_* | while read line; do
cat "$line" | grep "something"
done
Use ggrep .
ggrep -H -R -I "mysearchstring" *
para procurar um arquivo no unix contendo texto localizado no diretório atual ou em um subdiretório
Isso imprimirá o nome e o conteúdo dos arquivos somente recursivamente.
find . -type f -printf '\n\n%p:\n' -exec cat {} \;
Editar (versão aprimorada): imprime o nome e o conteúdo dos arquivos de texto (ascii) somente recursivamente.
find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'
Mais uma tentativa
find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;
Você está tentando encontrar texto nos arquivos? Você pode simplesmente usar grep para isso ...
grep searchterm *
Para listar e ver o conteúdo de todos os arquivos abc.def em um servidor nos diretórios / ghi e / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;
Para listar os arquivos abc.def que comentaram entradas e exibem, consulte essas entradas nos diretórios / ghi e / jkl
find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
find -name '*.foo' -printtrabalhou muito para mim ... Obrigado