esponja de moreutils - qual é a diferença para redirecionar shell? exemplos úteis?

15
> brew install moreutils                                                          
==> Downloading https://homebrew.bintray.com/bottles/moreutils-0.55.yosemite.bottle.tar.gz    
######################################################################## 100.0%               
==> Pouring moreutils0.55.yosemite.bottle.tar.gz       
🍺  /usr/local/Cellar/moreutils/0.55: 67 files, 740K   

esponja lê a entrada padrão e a grava no arquivo especificado. Ao contrário de um redirecionamento de shell, a esponja absorve toda a sua entrada antes de gravar o arquivo de saída. Isso permite a construção de pipelines que leem e gravam no mesmo arquivo.

Eu não entendo Por favor me dê alguns exemplos úteis.

O que significa absorve ?

Ivanov
fonte
Outro exemplo é expand foo.txt | sponge foo.txt. Veja também: stackoverflow.com/a/33639324/1959808
Ioannis Filippidis

Respostas:

32

Suponha que você tenha um arquivo chamado input, deseja remover todas as linhas iniciadas por #in input. Você pode fazer com que todas as linhas não comecem #usando:

grep -v '^#' input

Mas como você faz alterações input? Com o padrão de ferramentas POSIX, você precisa usar um arquivo temporário, algo como:

grep -v '^#' input >/tmp/input.tmp
mv /tmp/input.tmp ./input

Com redirecionamento de shell:

grep -v '^#' input >input

truncará inputantes de você ler.

Com sponge, você pode:

grep -v '^#' input | sponge input
cuonglm
fonte
4
Na verdade, você pode ler e gravar um arquivo ao mesmo tempo com segurança, desde que os bytes sejam apenas transformados, usando o <>operador.
Chris Baixo
@ChrisDown: Sim, quero dizer, sem torná-lo corroupt
cuonglm
Não sei o que você quer dizer com "torná-lo corrompido". Ao contrário do >e <, <>não corrompe o arquivo, a menos que algo dê errado. Você pode facilmente escrever byte byte usando-o. Por exemplo, tente usá-lo com tr.
Chris Baixo
@ ChrisDown: Deixe-me remover essa frase para evitar confusões. Na verdade, quero dizer que ao usar <>file, você abre um arquivo para leitura e gravação, mas na verdade não escreve nada para arquivar.
precisa saber é o seguinte
1
Acho que o ponto que @ChrisDown está tentando enfatizar é que <>não trunca um arquivo, mas apenas substitui seus bytes existentes pela nova saída. Se a nova saída for muito curta, você terá restos de lixo no final do arquivo. Mas se a nova saída for longa o suficiente, não haverá risco.
precisa
7

A própria home page do moreutils documenta um caso de uso típico:

sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd

Aqui, o / etc / passwd está sendo gravado e lido, e está sendo modificado. Sem aplicar stdin antes de escrever, o / etc / passwd pode estar corrompido (conforme o arquivo foi alterado durante a leitura).

Chris Down
fonte
E isso seria um bom exemplo na página moreutils, se tivesse explicado da maneira que você fez :-)
Br.Bill