Schwamm von moreutils - Was ist der Unterschied zur Shell-Umleitung? nützliche Beispiele?

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   

Schwamm liest die Standardeingabe und schreibt sie in die angegebene Datei. Im Gegensatz zu einer Shell-Umleitung nimmt der Schwamm alle Eingaben auf, bevor er die Ausgabedatei schreibt. Auf diese Weise können Pipelines erstellt werden, die aus derselben Datei lesen und in dieselbe Datei schreiben.

Ich verstehe nicht Bitte geben Sie mir einige nützliche Beispiele.

Was bedeutet aufsaugen ?

Ivanov
quelle
1
unix.stackexchange.com/search?q=sponge
Gilles ‚SO- Anschlag Sein Übel‘
Ein anderes Beispiel ist expand foo.txt | sponge foo.txt. Siehe auch: stackoverflow.com/a/33639324/1959808
Ioannis Filippidis

Antworten:

32

Angenommen, Sie haben eine Datei mit dem Namen input, und Sie möchten alle Zeilen entfernen, die mit #in beginnen input. Sie können alle Zeilen nicht mit beginnen #:

grep -v '^#' input

Aber wie nehmen Sie Änderungen vor input? Mit dem POSIX-Standard-Toolchest müssen Sie eine temporäre Datei verwenden, beispielsweise:

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

Mit Shell-Umleitung:

grep -v '^#' input >input

wird abgeschnitten, inputbevor Sie daraus lesen.

Mit spongekönnen Sie:

grep -v '^#' input | sponge input
cuonglm
quelle
4
Sie können eine Datei gleichzeitig sicher lesen und schreiben, solange die Bytes nur mit dem <>Operator transformiert werden .
Chris Down
@ChrisDown: Ja, ich meine , ohne es zu machen corroupt
cuonglm
Ich bin mir nicht sicher, was du mit "Verderben" meinst. Im Gegensatz zu >und <wird <>die Datei nur dann beschädigt, wenn wirklich ein Fehler aufgetreten ist. Sie können ganz einfach byteweise damit schreiben. Versuchen Sie es beispielsweise mit tr.
Chris Down
@ ChrisDown: Lassen Sie mich diesen Satz entfernen, um Verwirrung zu vermeiden. Eigentlich heißt das, wenn <>fileSie eine Datei zum Lesen und Schreiben öffnen, aber tatsächlich nichts in eine Datei schreiben.
cuonglm
1
Ich denke, der Punkt, den @ChrisDown anstrebt, ist, dass <>eine Datei nicht abgeschnitten wird, sondern lediglich die vorhandenen Bytes durch die neue Ausgabe ersetzt werden. Wenn die neue Ausgabe zu kurz ist, verbleibt am Ende der Datei Restmüll. Wenn die neue Ausgabe jedoch lang genug ist, besteht kein Risiko.
BallpointBen
7

Die Homepage von moreutils selbst dokumentiert einen typischen Anwendungsfall:

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

Hier wird / etc / passwd sowohl geschrieben als auch gelesen und geändert. Wenn Sie stdin nicht vor dem Schreiben auffrischen, ist / etc / passwd möglicherweise beschädigt (da sich die Datei während des Lesens geändert hat).

Chris Down
quelle
Und das wäre ein gutes Beispiel auf der Seite moreutils, wenn es erklärt hätte, wie Sie es getan haben :-)
Br.Bill