Inhalt einer Datei an den Befehl "echo" umleiten

41

Ich habe eine Datei mit dem Namen, my_file.txtderen Inhalt nur die Zeichenfolge ist Hello. Wie kann ich den Inhalt auf den Befehl umleiten echo?

Ich weiß , dass ich die Befehle haben less, cat, more... aber ich muss es mit dem tun echo.

Ich habe es versucht:

$ cat my_file.txt | echo

und auch das:

$ echo < my_file.txt

In beiden Fällen wird jedoch nur ein Leerzeichen in der stdout angezeigt, nicht der Inhalt von my_file.txt.

Wie könnte ich das machen?

danielmbcn
quelle
7
Warum bestehen Sie darauf echo?
Kevin
7
@ Kevin, vermutlich möchte er irgendwann die ANSI C-Escape-Sequenzen ( \n, b...) in der Datei erweitern, was eine gültige Verwendung von echo(zumindest eines Standards echo) wäre. Oder vermutlich will er verstehen, warum es nicht so funktioniert. In jedem Fall kein Grund, IMO abzustimmen.
Stéphane Chazelas
3
Ich bin hierher gekommen, weil ich neugierig war, warum es nicht funktioniert, wenn ich echo <file.txt mache. Scheint bei SE eine vernünftige Frage zu haben, die Antwort war sehr hilfreich. +1 von mir.
Neuronet

Antworten:

53

Sie können alles umleiten, was Sie wollen, echoaber es wird nichts damit anfangen. echoliest seine Standardeingabe nicht. Es wird lediglich in die Standardausgabe geschrieben, wobei die Argumente durch ein Leerzeichen getrennt und durch ein Zeilenumbruchzeichen abgeschlossen werden (und bei einigen echoImplementierungen werden einige Escape-Sequenzen darin erweitert und / oder Argumente beginnen mit -möglicherweise als Optionen behandelten).

Wenn Sie echoden Inhalt einer Datei anzeigen möchten , müssen Sie diesen Inhalt als Argument an übergeben echo. So etwas wie:

echo "$(cat my_file.txt)"

Beachten Sie, dass $(...)die hinteren Neue - Zeile - Zeichenstreifen s vom Ausgang dieses catBefehls, und echofügt einen Rücken.

Beachten zshSie auch, dass Sie mit Ausnahme von with keine NUL-Zeichen in den Argumenten eines Befehls übergeben können, sodass die oben genannten normalerweise nicht mit Binärdateien funktionieren. yashentfernt auch Bytes, die nicht Teil gültiger Zeichen sind.

Wenn der Grund für den Wunsch , das zu tun ist , weil Sie wollen echodas erweitern \n, \b, \0351... Escape - Sequenzen in der Datei (wie UNIX - konforme echoImplementierungen zu tun, aber nicht alle ), dann würden Sie lieber verwenden printfstatt :

printf '%b\n' "$(cat my_file.txt)"

Im Gegensatz dazu echoist diese portabel und hat keine Probleme, wenn der Inhalt der Datei mit beginnt -.


Als Alternative zu $(cat file), mit ksh, zshund bashkann man auch tun:$(<file) . Dies ist ein spezieller Operator, bei dem die Shell im Gegensatz zum catLesen den Inhalt der Datei liest, um die Erweiterung zu bilden. Es werden weiterhin die nachgestellten Zeilenumbrüche und Drosseln auf NUL-Bytes außer in entfernt zsh. In bash, das gabelt noch einen zusätzlichen Prozess. Beachten Sie auch, dass ein Unterschied darin besteht, dass beim Versuch, eine Datei des Typs directory auf diese Weise zu lesen, keine Fehler auftreten. Solange $(< file)es etwas Besonderes ist, $(< file; other command)ist es auch nichts ( zshwenn Sie keine andere Shell emulieren, würde dies den Inhalt der Shell trotzdem erweitern file, indem Sie den impliziten $READNULLCMD Befehl ausführen (normalerweise einen Pager)).

Stéphane Chazelas
quelle
3
In beiden bash und zsh können Sie die überspringen catund nur noch die Schale in direkt lesen: echo "$(<my_file.txt)".
Kevin
1
Ja, mit ksh , zsh und bash können Sie verwenden $(<filename).
Dimitre Radoulov
Vielen Dank, das habe ich gebraucht und es hat funktioniert! :-)
Danielmbcn
@ Kevin, Dimitre, jetzt hinzugefügt.
Stéphane Chazelas
4

Neben anderen Antworten können Sie auch die Eingabeumleitung anstelle von verwenden cat

echo $(<my_file.txt)

oder

echo `<my_file.txt`

$()und `` führen dasselbe aus, sie führen Befehle innerhalb ihres Gültigkeitsbereichs aus und geben die Ausgabe an die Shell weiter, als ob sie vom Benutzer als Eingabe übergeben worden wäre. Der einzige Unterschied zwischen diesen beiden ist, dass $ () rekursiv und `` nicht rekursiv sein kann.

GypsyCosmonaut
quelle
2

Einfache Antwort: Sie können nicht. echo(sei es in der Shell eingebaut oder als reguläre Binärdatei) verarbeitet die Standardeingabe nicht - es ist nur eine Möglichkeit.

peterph
quelle
Die Frage ist, warum möchten Sie das eigentlich tun?
Peterph
2

Wie gesagt,

Wenn Sie echoden Inhalt einer Datei anzeigen möchten , müssen Sie diesen Inhalt als Argument an übergebenecho

Zum Beispiel können Sie dies folgendermaßen tun xargs(vorausgesetzt, Sie müssen die Interpretation von Backslash-Escapes aktivieren ):

$ cat my_file.txt | xargs echo -e

Oder einfach, was Sie gefragt haben (ohne Interpretation von Escape- Sequenzen ):

$ cat my_file.txt | xargs echo
Kenichi
quelle
Beachten Sie jedoch, dass bei der Verwendung xargs echo( xargsgenau wie echobeim Standardbefehl) der echoBefehl aus dem Dateisystem ausgeführt wird, nicht der integrierte echoBefehl der Shell . Beachten Sie auch, xargsdass die Eingabe in einem sehr speziellen Format erwartet wird (Leerzeichen, Zeilenumbrüche, Anführungszeichen und umgekehrte Schrägstriche haben eine besondere Bedeutung). cathier nicht machen viel Sinn , da es nur eine Datei zu verketten (gleich wie < file.txt xargs echoHinweis , dass Unix - kompatibel. echos tun Backslash Escape - Expansion von Standard und Ausgang -eauf echo -e.
Stéphane Chazelas
0

In bash sollte auch folgendes funktionieren:

echo `cat my_file.txt`

Der Teil in Backticks wird durch die Ausgabe dieses Befehls ersetzt, dh in diesem Fall durch den Dateiinhalt.

Motlib
quelle
Richtig, Backticks funktionieren wie $( . . . ). Leute, die sie $()normalerweise benutzen, bevorzugen sie, weil man sie nisten kann. Diese Frage ist alt, aber es ist viel befriedigender, Fragen zu beantworten, die noch nicht beantwortet wurden!
Law29
Nicht ganz. Es gibt einen subtilen Unterschied. Wenn das Back-Tick-Formular verwendet wird, behält ein Backslash seine wörtliche Bedeutung bei, außer wenn $, `oder \ folgen. Das erste Back-Tick ohne vorangestelltem Backslash beendet den Befehl. Bei Verwendung des Formulars $ (,,,) bilden alle Zeichen in Klammern den Befehl.
Fpmurphy
Da diese Befehlsersetzung nicht in Anführungszeichen steht, wird der Operator split + glob darauf angewendet. Wenn zum Beispiel my_file.txtenthält *, wird die Liste der Dateinamen im aktuellen Verzeichnis gedruckt.
Stéphane Chazelas