Como usar o comando "cat" na saída do comando "find"?


13

Quero redirecionar a saída do findcomando para catcomando, para poder imprimir os dados do arquivo fornecido.

Por exemplo, se a saída de find for /aFile/readme, o gato deve ser interpretado como cat ./aFile/readme. Como posso fazer isso instantaneamente?

Eu tenho que usar canos?

Eu tentei versões disso:

cat | find ./inhere -size 1033c 2> /dev/null

Mas acho que isso está completamente errado? Claro que tenho certeza de que a saída é apenas um arquivo e não vários arquivos.

Então, como posso fazer isso? Pesquisei no Google e não consegui encontrar uma solução, provavelmente porque não pesquisei direito: P

Respostas:


21

Você pode fazer isso findsozinho usando a -execação:

find /location -size 1033c -exec cat {} +

{}será expandido para os arquivos encontrados e +nos permitirá ler o maior número possível de argumentos por chamada cat, pois cat pode receber vários argumentos.

Se você findnão possui a +extensão ou deseja ler os arquivos um por um:

find /location -size 1033c -exec cat {} \;

Se você deseja usar qualquer opção de cat, faça:

find /location -size 1033c -exec cat -n {} +
find /location -size 1033c -exec cat -n {} \;

Aqui estou usando a -nopção para obter os números de linha.


Então, se eu estiver correto: {} é como uma variável que contém a saída do comando find e, após o sinal "+", você deve escrever os parâmetros do gato? Não ? Edit: Tudo bem, você editou sua postagem e agora acabou de responder minha pergunta: P Thanx man! Resolvido!
Eksapsy

@ general656 Verifique minhas edições ..
heemayl

1
O fato de eu não conhecer cata -nopção me surpreende. Adoro ler perguntas aleatórias.
mazunki

0

Substituição de Comando

Outra opção é usar a Substituição de Comando . A quebra de um comando $()executará o comando e substituirá o comando por sua saída.

cat $(find ./inhere -size 1033c 2> /dev/null)

se tornará

cat ./inhere/file1 .inhere/file3

Isso é mais ou menos equivalente ao uso do estilo antigo de agrupar comandos com back ticks:

cat `find ./inhere -size 1033c 2> /dev/null`

Mais detalhes dos documentos vinculados acima

O Bash executa a expansão executando o comando em um ambiente de subshell e substituindo a substituição do comando pela saída padrão do comando, com as novas linhas finais excluídas. As novas linhas incorporadas não são excluídas, mas podem ser removidas durante a divisão de palavras. A substituição do comando $(cat file)pode ser substituída pelo equivalente, mas mais rápido $(< file).

Quando a forma de acento grave do velho estilo de substituição é utilizado, barra invertida mantém o seu significado literal excepto quando seguido por $, `, ou \. A primeira cotação anterior não precedida por uma barra invertida finaliza a substituição do comando. Ao usar o $(command)formulário, todos os caracteres entre parênteses formam o comando; nenhum é tratado especialmente.

As substituições de comando podem estar aninhadas. Para aninhar ao usar o formulário com aspas anteriores, escape das aspas internas internas com barras invertidas.

Se a substituição aparecer entre aspas duplas, a divisão de palavras e a expansão do nome do arquivo não são executadas nos resultados.

Veja esta outra resposta para alguns bons exemplos de uso.


Observe que, se findencontrar muitos arquivos, isso geraria um erro "lista de argumentos muito longa" ao tentar invocar cat. Também teria problemas ao manipular nomes de arquivos que contenham caracteres de espaço em branco e possivelmente também nomes de arquivos que contenham caracteres ocultos de nome de arquivo.
Kusalananda

-1

Isso imprimirá 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 {} \;

-2

Use pipe e xargs

find /* -name pg_hba.conf | xargs cat

Se falhar devido à falta de permissões, você poderá usar o sudo para garantir que tenha permissão para executar o comando find no diretório que está pesquisando.

 sudo find /* -name pg_hba.conf | xargs sudo cat

1
E se alguém criou um arquivo chamado /tmp/ /dev/urandom /pg_hba.conf, isso permitirá que o root despeje todo o conteúdo de /dev/urandom. Provavelmente, o pior pode ser feito dependendo do contexto. xargsquase nunca deve ser usado sem, -0se for o caso. Também sudo xargsseria melhor que xargs sudo. E /*seria melhor como /.
Stéphane Chazelas

1
O OP quer usar cat para imprimir o conteúdo do arquivo no stdout. Portanto, o objetivo é servido pelo gato. A questão é como usar o gato do comando out put of find para imprimir o conteúdo do arquivo e não como usar o sudo ou o find. O comando acima resolve a questão. Sim xargs -0 foi a única coisa construtiva que você apontou. Mas não mostrou o uso. Tente não ser rude.
App Work

Desculpe se isso parece rude. Essa não era a intenção. Eu queria apontar as limitações. Sua resposta mostra más práticas ( find|xargssem -0realmente deve ser banida), daí o voto negativo. A saída de findsem -print0não é pós-processável de forma confiável. -print0não é padrão. Dito isso, o padrão sudo find / -name pg_hba.conf -exec cat {} +também pode fazer com que você despeje o conteúdo /dev/urandom(por exemplo, se alguém criou um link simbólico /tmp/pg_hba.confpara ele e não há uma maneira portátil fácil de contornar isso que não tenha pelo menos uma condição de corrida).
Stéphane Chazelas

1
Não vamos usar sudo"apenas por precaução", devemos?
Lindhe 19/07

Bem, é melhor do que corrersudo rm -rf /
devinbost
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.