Wie von anderen angemerkt, schlägt Ihr ursprünglicher Befehl fehl, weil cat 1.txtseine Standardeingabe ignoriert wird. Geben Sie entweder an, dass es das erste Argument ( cat - 1.txt) sein soll, oder verwenden Sie die Blockumleitung , um echo abcundcat 1.txt zusammen umzuleiten . Nämlich:
Zusammengesetzte Befehle
Ein zusammengesetzter Befehl ist einer der folgenden. In den meisten Fällen kann eine Liste in der Beschreibung eines Befehls durch eine oder mehrere Zeilenumbrüche vom Rest des Befehls getrennt sein, gefolgt von einer neuen Zeile anstelle eines Semikolons.
(aufführen)
Die Liste wird in einer Subshell-Umgebung ausgeführt (siehe COMMAND EXECUTION ENVIRONMENT unten). Variablenzuweisungen und integrierte Befehle, die sich auf die Umgebung der Shell auswirken, bleiben nach Abschluss des Befehls nicht wirksam. Der Rückgabestatus ist der Beendigungsstatus der Liste.
{aufführen;}
list wird einfach in der aktuellen Shell-Umgebung ausgeführt.
Die Liste muss mit einem Zeilenumbruch oder einem Semikolon abgeschlossen werden. Dies wird als Gruppenbefehl bezeichnet . Der Rückgabestatus ist der Beendigungsstatus der Liste . Beachten Sie, dass im Gegensatz zu dem Meta - Zeichen (und ),
{und }sind reservierte Worte und muß dort auftreten , wo ein reserviertes Wort erkannt werden darf. Da sie keinen Wortumbruch verursachen, müssen sie
durch Leerzeichen oder ein anderes Shell-Metazeichen von der Liste getrennt werden .
Die erste Option (Subshell-Umgebung) hat eine Reihe von Nebenwirkungen, von denen die meisten, wenn nicht alle, für Ihr Szenario irrelevant sind. Wenn Sie jedoch nur die Ausgabe einer Reihe von Befehlen umleiten möchten, wird Option 2 hier (Gruppenbefehl) bevorzugt.
Sie haben die Echoausgabe an cat weitergeleitet, aber cat hatte keine Verwendung für die Eingabe und hat sie ignoriert. Jetzt werden die Befehle nacheinander ausgeführt und ihre Ausgabe wird gruppiert (die Klammern) und in 2.txt geleitet.
Diese Antwort kann verbessert werden, indem erklärt wird, wie es funktioniert und warum der ursprüngliche Versuch des OP nicht funktioniert.
Bob
OK, habe es versucht.
Gerard H. Pille
5
Eine Unterschale ist hier nicht ausdrücklich erforderlich, vielleicht ist es besser, einen Gruppenbefehl zu verwenden. Siehe meine Antwort für weitere Details.
Diese Antwort kann verbessert werden, indem erklärt wird, warum der ursprüngliche Versuch des OP nicht funktioniert (und warum dies stattdessen erforderlich ist).
Bob
1
Die <(command)Konstruktion ist eine Bash-Erweiterung. Es ist kein POSIX, daher können Sie sich in Skripten, mit denen ausgeführt werden soll, nicht darauf verlassen /bin/sh.
Rhialto unterstützt Monica
0
Nur eine Vermutung, aber es sieht so aus, als hätten Sie einen wiederholbaren Prozess, der ein guter Kandidat für einen Alias oder eine Funktion ist. Aliase sind normalerweise Abkürzungen zum Aufrufen von Bash-Befehlen, wie z. B. Abkürzung, für einen einzelnen Eingabestream als Argument.
alias hg="history | grep"
In diesem Fall wäre eine Funktion jedoch besser lesbar, da Sie mehrere diskrete (2) Eingabestreams sowie mehrere Bash-Befehle kombinieren. Sie haben zwei Argumente, das erste ist eine Zeichenfolge und das andere ein Dateipfad. Am Ende möchten Sie, dass das Ergebnis in den Standardausgabestream geschrieben wird.
Geben Sie an einer CLI-Eingabeaufforderung Folgendes ein:
# ecat()
{
echo ${1}
cat ${2}
}
Ihre Funktion heißt ecat, was unvergesslich ist.
Jetzt können Sie als aufrufen
ecat "abc" 1.txt
Geben Sie zum Anhängen einfach ein anderes Ausgabeziel an stdout an:
ecat "abc" 1.txt >> 2.txt
Der Append-Umleitungsoperator '>>' fügt die Ausgabe am Ende der angegebenen Datei hinzu.
Wenn es Ihnen gefällt, hängen Sie es zur Wiederverwendung an Ihre ~ / .bashrc-Datei an.
declare -f ecat >> ~/.bashrc
Das bedeutet auch, dass Sie innerhalb Ihrer Funktionsdefinition usw. dekorieren können.
Auch eine gute Idee, um Dateien vor dem Überschreiben zu schützen, indem Sie diese zu Ihrem ~ / .bashrc hinzufügen
Wie reagiert der noclobberVorschlag auf die vorliegende Frage? (Ich bin auch nicht sehr davon überzeugt, dass es ein guter Rat ist - das Ändern des globalen Verhaltens führt dazu, dass Skripte / Ratschläge / Praktiken, die unter Berücksichtigung der Standardeinstellungen erstellt wurden, beschädigt werden.)
Charles Duffy
0
Der folgende Code funktioniert auch:
echo abc >> 1.txt && cat 1.txt > 2.txt
Die Ausgabe von echo abc wird mit >> an 1.txt angehängt.
Danach weist das && an, den nächsten Befehlssatz auszuführen, der 1.txt enthält, und gibt ihn dann an 2.txt aus . Grundsätzlich hängt es die Ausgabe des ersten Befehls an 1.txt an und sendet dann die Ausgabe von 1.txt an 2.txt.
Wenn der abc zuerst angezeigt werden soll, können Sie den folgenden Code verwenden:
Dies wird (1) abcam Ende von setzen 2.txt; Die Frage will es ganz oben. (2) die Datei ändern1.txt ; das ist inakzeptabel.
G-Man sagt "Reinstate Monica"
Wo steht das? Ringger81 hat nie angegeben, wo in 2.txt abc erscheinen soll. Sie gehen von Dingen aus, die in der Frage niemals stehen.
Nasir Riley
(1) OK, Sie erhöhen einen gültigen Punkt auf # 1. Während die Frage im Text "Ausgabe vom Echo" vor "Inhalt einer Datei" erwähnt und dann den Befehl " echovor dem Beispiel" catin den Beispielbefehl einfügt, wird vermutlich nie genau explizit angegeben , dass die Ausgabe vom Echo vor dem Inhalt der Eingabedatei. Es scheint nur, dass die meisten Leute es so interpretierten. (2) 1.txtist eine Eingabedatei. Die Frage sagt nichts über das Ändern aus 1.txt. Die Tatsache, dass Eingabedateien nicht geändert werden sollten, versteht sich von selbst.
G-Man sagt "Reinstate Monica"
Ich kann Ihren Standpunkt verstehen, die Imput-Datei nicht zu ändern. Mein zweiter Code erzielt den gewünschten Effekt, ohne dies zu tun.
Nasir Riley
1
Öffnen einer Datei, Anhängen, Schließen , erneutes Öffnen, erneutes Anhängen ... Warum tun Sie das, anstatt sie nur einmal zu öffnen und die Umleitung für beide Vorgänge beizubehalten?
cat
lesen nur gerne von der Standardeingabe, wenn sie keine Dateinamenargumente haben.Antworten:
Es funktioniert nicht, weil das
cat
Programm in Ihrer Pipe-Sequenz nicht angewiesen wurde, dieecho
Programmausgabe von der Standardeingabe zu lesen .Sie können
-
einen Pseudodateinamen verwenden, um die Standardeingabe anzugebencat
. Abman cat
einer msys2-Installation:Also versuche
stattdessen.
quelle
Wie von anderen angemerkt, schlägt Ihr ursprünglicher Befehl fehl, weil
cat 1.txt
seine Standardeingabe ignoriert wird. Geben Sie entweder an, dass es das erste Argument (cat - 1.txt
) sein soll, oder verwenden Sie die Blockumleitung , umecho abc
undcat 1.txt
zusammen umzuleiten . Nämlich:Relevanter Auszug aus dem Handbuch (
man bash
):Die erste Option (Subshell-Umgebung) hat eine Reihe von Nebenwirkungen, von denen die meisten, wenn nicht alle, für Ihr Szenario irrelevant sind. Wenn Sie jedoch nur die Ausgabe einer Reihe von Befehlen umleiten möchten, wird Option 2 hier (Gruppenbefehl) bevorzugt.
quelle
Sie haben die Echoausgabe an cat weitergeleitet, aber cat hatte keine Verwendung für die Eingabe und hat sie ignoriert. Jetzt werden die Befehle nacheinander ausgeführt und ihre Ausgabe wird gruppiert (die Klammern) und in 2.txt geleitet.
quelle
bash(1)
, beschreibt sie das Verhalten, das jede POSIX-kompatible Shell unterstützen muss.Ihr Befehl
cat 1.txt
macht nichts mit der Ausgabe vonecho "abc"
.Stattdessen:
(echo "abc"; cat 1.txt) > 2.txt
schreibt die Ausgabe beider Befehle in 2.txt.quelle
In jeder POSIX-Shell können Sie die Befehlssubstitution
cat file
als Eingabe für Folgendes verwendenecho
:In Bash können Sie die Prozessersetzung verwenden und echo als eine andere "Datei" verwenden
cat
, wie in:und leiten Sie die Ausgabe dann nach Belieben weiter oder leiten Sie sie um.
Wie jede andere Antwort sagt, ignoriert Katze stdin, wenn sie eine Datei zum Anschauen hat. (Ich mag auch die Antworten von Daniel & mvw, +1 für sie)
quelle
<(command)
Konstruktion ist eine Bash-Erweiterung. Es ist kein POSIX, daher können Sie sich in Skripten, mit denen ausgeführt werden soll, nicht darauf verlassen/bin/sh
.Nur eine Vermutung, aber es sieht so aus, als hätten Sie einen wiederholbaren Prozess, der ein guter Kandidat für einen Alias oder eine Funktion ist. Aliase sind normalerweise Abkürzungen zum Aufrufen von Bash-Befehlen, wie z. B. Abkürzung, für einen einzelnen Eingabestream als Argument.
In diesem Fall wäre eine Funktion jedoch besser lesbar, da Sie mehrere diskrete (2) Eingabestreams sowie mehrere Bash-Befehle kombinieren. Sie haben zwei Argumente, das erste ist eine Zeichenfolge und das andere ein Dateipfad. Am Ende möchten Sie, dass das Ergebnis in den Standardausgabestream geschrieben wird.
Geben Sie an einer CLI-Eingabeaufforderung Folgendes ein:
Ihre Funktion heißt ecat, was unvergesslich ist.
Jetzt können Sie als aufrufen
Geben Sie zum Anhängen einfach ein anderes Ausgabeziel an stdout an:
Der Append-Umleitungsoperator '>>' fügt die Ausgabe am Ende der angegebenen Datei hinzu.
Wenn es Ihnen gefällt, hängen Sie es zur Wiederverwendung an Ihre ~ / .bashrc-Datei an.
Das bedeutet auch, dass Sie innerhalb Ihrer Funktionsdefinition usw. dekorieren können.
Auch eine gute Idee, um Dateien vor dem Überschreiben zu schützen, indem Sie diese zu Ihrem ~ / .bashrc hinzufügen
quelle
"$1"
und verwenden"$2"
. In diesem Zusammenhang nützen die geschweiften Klammern nichts. Siehe${name}
bedeutet nicht , was Sie denken , es tut ... .noclobber
Vorschlag auf die vorliegende Frage? (Ich bin auch nicht sehr davon überzeugt, dass es ein guter Rat ist - das Ändern des globalen Verhaltens führt dazu, dass Skripte / Ratschläge / Praktiken, die unter Berücksichtigung der Standardeinstellungen erstellt wurden, beschädigt werden.)Der folgende Code funktioniert auch:
Die Ausgabe von echo abc wird mit >> an 1.txt angehängt. Danach weist das && an, den nächsten Befehlssatz auszuführen, der 1.txt enthält, und gibt ihn dann an 2.txt aus . Grundsätzlich hängt es die Ausgabe des ersten Befehls an 1.txt an und sendet dann die Ausgabe von 1.txt an 2.txt.
Wenn der abc zuerst angezeigt werden soll, können Sie den folgenden Code verwenden:
quelle
abc
am Ende von setzen2.txt
; Die Frage will es ganz oben. (2) die Datei ändern1.txt
; das ist inakzeptabel.echo
vor dem Beispiel"cat
in den Beispielbefehl einfügt, wird vermutlich nie genau explizit angegeben , dass die Ausgabe vom Echo vor dem Inhalt der Eingabedatei. Es scheint nur, dass die meisten Leute es so interpretierten. (2)1.txt
ist eine Eingabedatei. Die Frage sagt nichts über das Ändern aus1.txt
. Die Tatsache, dass Eingabedateien nicht geändert werden sollten, versteht sich von selbst.