spugna di moreutils - qual è la differenza con il reindirizzamento delle shell? esempi utili?


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   

sponge legge l'input standard e lo scrive nel file specificato. A differenza del reindirizzamento della shell, sponge assorbe tutto il suo input prima di scrivere il file di output. Ciò consente di costruire pipeline che leggono e scrivono nello stesso file.

Non capisco. Per favore, dammi alcuni esempi utili.

Cosa significa assorbire ?



Un altro esempio è expand foo.txt | sponge foo.txt. Vedi anche: stackoverflow.com/a/33639324/1959808
Ioannis Filippidis

tl; dr sponge"assorbe" il suo input prima di troncare il file di output
BallpointBen

Risposte:


33

Supponiamo di avere un file denominato input, che si desidera rimuovere tutte le righe che iniziano con #in input. Puoi ottenere che tutte le linee non inizino con #:

grep -v '^#' input

Ma come si apportano modifiche input? Con il toolchest POSIX standard, è necessario utilizzare un file temporaneo, ad esempio:

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

Con reindirizzamento delle shell:

grep -v '^#' input >input

troncerà inputprima di leggere da esso.

Con sponge, puoi:

grep -v '^#' input | sponge input

4
In realtà è possibile leggere e scrivere un file allo stesso tempo in modo sicuro purché i byte vengano trasformati solo tramite l' <>operatore.
Chris Down,

@ChrisDown: Sì, intendo senza renderlo corroupt
cuonglm

Non sono sicuro di cosa intendi per "renderlo corrotto". A differenza di >e <, <>non corrompe il file a meno che qualcosa non sia andato davvero storto. Puoi facilmente scrivere byte per byte utilizzandolo. Ad esempio, prova ad usarlo con tr.
Chris Down,

@ChrisDown: lasciami rimuovere quella frase per evitare confusione. In realtà intendo quando si utilizza <>file, si apre il file per la lettura e la scrittura, ma in realtà non si scrive nulla su file.
cuonglm,

1
Penso che il punto che @ChrisDown sta cercando di chiarire sia che <>non tronca un file, ma sostituisce semplicemente i suoi byte esistenti con il nuovo output. Se il nuovo output è troppo corto, alla fine del file avrai immondizia residua. Ma se il nuovo output è abbastanza lungo, non c'è rischio.
BallpointBen,

8

La home page di moreutils stessa documenta un tipico caso d'uso:

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

Qui / etc / passwd viene sia scritto che letto su, e viene modificato. Senza spugnare stdin prima di scrivere, / etc / passwd potrebbe essere danneggiato (poiché il file è cambiato durante la lettura).


E questo sarebbe un buon esempio sulla pagina di moreutils, se avesse spiegato come hai fatto :-)
Fr. Bill
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.