output to file, então use o arquivo para entrada

7

Existe uma maneira mais curta de escrever isso? Basicamente, envie um comando para um arquivo e use o arquivo como entrada para o próximo comando. Eu também quero manter o arquivo para ver depois.

cmd1 > verylong.txt; cmd2 < verylong.txt

Eu sei que posso fazer

cmd1 | tee verylong.txt | cmd2

Mas como espero que "verylong.txt" seja um arquivo enorme, achei que seria menos eficiente usar o pipe, pois ele armazenaria todo o arquivo na memória. Considerando que, se eu usar a entrada de arquivo, ele processaria uma linha por vez. (Ou a minha suposição está errada?)

Seria ótimo se eu pudesse fazer algo elegante como

cmd1 > verylong.txt > cmd2

    
por wisbucky 20.11.2014 / 23:49

4 respostas

15

Até onde eu sei, cmd1 | tee verylong.txt | cmd2 não irá armazenar todo o arquivo na memória. De fato, se cmd2 precisasse esperar muito antes de consumir sua entrada, cmd1 poderia bloquear uma chamada write e desbloquear somente quando cmd2 começasse a ler novamente.

A razão para isso é que há um buffer para o pipe e esse buffer, por padrão, está limitado a um determinado tamanho razoável .

Naturalmente, a história pode ser diferente se cmd2 for sort (ou algo parecido) em que toda a entrada deve ser lida antes que o comando possa gravar sua saída. Nesse caso, todo o conteúdo do arquivo pode ser mantido em cmd2 memory, mas isso é independente se um pipe ou um arquivo intermediário foi usado para a entrada desse comando.

    
por 21.11.2014 / 01:15
6

A resposta já dada está correta. Mas se seu objetivo é ler seletivamente seu verylongfile.txt w / cmd2 , sed pode ser outra opção.

cmd1 | sed -e 'w verylongfile.txt' -e '/notinteresting/d' | cmd2

sed irá w rite todas as suas entradas para o outfile, mas apenas os bits que não correspondem ao endereço /notinteresting/ para o pipe. Ou você pode negar a ação com /interesting/!d , que gravaria apenas as linhas que correspondem ao endereço interesting ao pipe.

Se este não for seu objetivo, use tee , porém - é uma ferramenta mais eficiente para gravar toda a sua entrada no outfile e no pipe.

    
por 21.11.2014 / 01:25
0

Existe um truque inteligente com tee e subshells:

cat source.lst | tee >(doSomething.sh) >(somethingElse.sh) | somethingFinal.sh

Eu fiz isso antes

pv -perl source.list | tee >(doSomething.sh) >(somethingElse.sh) | md5sum

pv fornecerá uma barra de progresso, um ETA e um total de linhas em execução. Em seguida, source.lst será alimentado para doSomething.sh e somethingElse.sh (e em CPUs diferentes!) Finalmente, obteremos um md5sum desse arquivo enorme, apenas para fins acadêmicos.

    
por 26.11.2014 / 15:55
-5

O que há de errado com o arquivo em lote simples de duas linhas? Como:

Cmd1 >filespec
Cmd2 <filespec

Ou

cmd1 >filespec
cmd2 filespec

de qualquer forma, o arquivo é deixado no armazenamento em massa.

    
por 21.11.2014 / 05:26