esponja de moreutils: ¿cuál es la diferencia con la redirección de shell? ejemplos útiles?

16
> 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   

la esponja lee la entrada estándar y la escribe en el archivo especificado. A diferencia de un redireccionamiento de shell, la esponja absorbe toda su entrada antes de escribir el archivo de salida. Esto permite construir tuberías que leen y escriben en el mismo archivo.

No entiendo. Por favor, dame algunos ejemplos útiles.

¿Qué significa absorber ?

Ivanov
fuente
1
unix.stackexchange.com/search?q=sponge
Gilles 'SO- deja de ser malvado'
Otro ejemplo es expand foo.txt | sponge foo.txt. Ver también: stackoverflow.com/a/33639324/1959808
Ioannis Filippidis el
tl; dr sponge"absorbe" su entrada antes de truncar el archivo de salida
BallpointBen

Respuestas:

33

Suponga que tiene un archivo llamado input, desea eliminar todas las líneas que comienzan con #in input. Puede obtener que todas las líneas no comiencen con #:

grep -v '^#' input

Pero, ¿cómo haces cambios input? Con el estándar POSIX toolchest, necesita usar un archivo temporal, algo como:

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

Con redireccionamiento de shell:

grep -v '^#' input >input

se truncará inputantes de leerlo.

Con spongeusted puede:

grep -v '^#' input | sponge input
Cuonglm
fuente
44
En realidad, puede leer y escribir un archivo al mismo tiempo de forma segura siempre que los bytes solo se transformen, utilizando el <>operador.
Chris Down
@ChrisDown: Sí, quiero decir sin hacer que se corrupe
cuonglm
No estoy seguro de lo que quieres decir con "corromperlo". A diferencia de >y <, <>no corrompe el archivo a menos que algo salga realmente mal. Puedes escribir byte por byte con bastante facilidad. Por ejemplo, intente usarlo con tr.
Chris Down
@ChrisDown: Déjame eliminar esa oración para evitar confusiones. En realidad, cuando uso <>file, abres un archivo para leer y escribir, pero en realidad no escribes nada en el archivo.
Cuonglm
1
Creo que el punto que @ChrisDown está tratando de hacer es que <>no trunca un archivo, sino que simplemente reemplaza sus bytes existentes con la nueva salida. Si la nueva salida es demasiado corta, tendrá restos de basura al final del archivo. Pero si la nueva salida es lo suficientemente larga, no hay riesgo.
BallpointBen
8

La propia página de inicio de moreutils documenta un caso de uso típico:

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

Aquí, / etc / passwd está siendo escrito y leído, y está siendo modificado. Sin usar el stdin antes de escribir, / etc / passwd podría estar dañado (ya que el archivo cambió durante la lectura).

Chris Down
fuente
Y ese sería un buen ejemplo en la página moreutils, si hubiera explicado la forma en que lo hizo :-)
Br.Bill