Ausgabe in Datei, dann Datei für Eingabe verwenden

7

Gibt es eine kürzere Schreibweise? Geben Sie grundsätzlich einen Befehl in eine Datei aus und verwenden Sie die Datei dann als Eingabe für den nächsten Befehl. Ich möchte auch die Datei behalten, um sie anschließend anzuzeigen.

cmd1 > verylong.txt; cmd2 < verylong.txt

Ich weiß, dass ich es kann

cmd1 | tee verylong.txt | cmd2

Da ich jedoch erwarte, dass "verylong.txt" eine riesige Datei ist, dachte ich, es wäre weniger effizient, Pipe zu verwenden, da dies die gesamte Datei im Speicher halten würde. Wenn ich dagegen eine Dateieingabe verwende, wird diese zeilenweise verarbeitet. (Oder ist meine Annahme falsch?)

Es wäre toll, wenn ich so etwas Elegantes machen könnte

cmd1 > verylong.txt > cmd2

wisbucky
quelle

Antworten:

15

Soweit ich weiß, cmd1 | tee verylong.txt | cmd2wird nicht die gesamte Datei im Speicher gehalten. Wenn Sie cmd2zu lange warten, bevor Sie die Eingabe verbrauchen, wird cmd1ein writeAnruf möglicherweise blockiert und erst dann entsperrt, wenn Sie cmd2erneut mit dem Lesen beginnen.

Der Grund dafür ist, dass es einen Puffer für die Pipe gibt und dieser Puffer standardmäßig auf eine bestimmte angemessene Größe beschränkt ist .

Natürlich könnte die Geschichte anders sein , wenn cmd2ist sort(oder so ähnlich) , in dem der gesamten Eingang vor dem Befehl gelesen werden muß , ist in der Lage seinen Ausgang zu schreiben. In diesem Fall wird möglicherweise der gesamte Dateiinhalt im cmd2Speicher gespeichert, dies ist jedoch unabhängig davon, ob für die Eingabe dieses Befehls eine Pipe- oder eine Zwischendatei verwendet wurde.

user43791
quelle
3
sortspeichert nicht die gesamte Datei im Speicher, sondern verfügt über einen Puffer mit maximaler Größe und greift auf temporäre Dateien zurück, wenn dieses Maximum erreicht ist.
Stéphane Chazelas
@ StéphaneChazelas Gut zu wissen, eine positive Bewertung! ;) Ich werde die Antwort aktualisieren, um in diesem Teil "In Erinnerung behalten" weniger durchsetzungsfähig zu sein.
user43791
6

Die bereits gegebene Antwort ist richtig. Aber wenn Ihr Ziel darin besteht, Ihr verylongfile.txtw / selektiv zu lesen cmd2, sedkönnte dies eine andere Option sein.

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

sedwird walle seine Eingabe in den outfile Ritus, sondern nur die Bits, die nicht übereinstimmen /notinteresting/Adresse an das Rohr. Oder Sie negieren die Aktion, mit /interesting/!dder nur die Zeilen geschrieben werden, die der interestingAdresse der Pipe entsprechen.

Wenn dies nicht Ihr Ziel ist, verwenden Sie es teestattdessen - es ist ein effizienteres Werkzeug, um die gesamte Eingabe sowohl in die Outfile als auch in die Pipe zu schreiben.

mikeserv
quelle
0

Es gibt einen cleveren Trick mit Tee und Subshells:

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

Ich habe das schon mal gemacht

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

pvSie erhalten einen Fortschrittsbalken, eine ETA und eine laufende Liniensumme. Dann wird source.lst an doSomething.sh und SomethingElse.sh (und auf verschiedenen CPUs!) Gefüttert. Schließlich erhalten wir eine MD5-Summe dieser riesigen Datei, nur für akademische Zwecke.

Dan Garthwaite
quelle
-5

Was ist los mit einfachen zweizeiligen Batch-Dateien? Mögen:

Cmd1 >filespec
Cmd2 <filespec

Oder

cmd1 >filespec
cmd2 filespec

In beiden Fällen bleibt die Datei im Massenspeicher.

user92319
quelle
Aus irgendeinem Grund lässt mich die Site kein Symbol weniger als eingeben. und den zweiten Teil von cmd2 fallen lassen. Also in Worten cmd1 in Datei umleiten. nächste Zeile cmd2 aus Datei umleiten. ODER für cmd2 geben Sie einfach den Dateinamen als ersten Parameter ein und cmd2 öffnet nur die Datei.
user92319
Sie verwenden &lt;für das <Symbol ...
Jasonwryan
1
Ein Unterschied zwischen cmd | tee file | cmdund cmd >file; cmd <filebesteht darin, dass die Befehle in der ersten Gruppe parallel ausgeführt werden - das heißt, dass sie alle gleichzeitig starten. Auf diese Weise cmd2kann die cmd1Ausgabe so verarbeitet werden, wie sie geschrieben wurde, während cmd1; cmd2zwei Befehle nacheinander ausgeführt werden - oder mit anderen Worten cmd2warten müssen, cmd1bis sie abgeschlossen sind, bevor etwas verarbeitet wird.
Mikeserv
Der Autor der Frage hat speziell nach einem anderen Befehl gefragt, da die Dateien sehr groß sind. Das Ausführen der Dateien mit Ihrer Methodik wäre viel langsamer als cmd1 | tee file | cmd2.
Mark D