Ein Programm, das stdin oder file puffern könnte

12

Abgesehen von der Verwendung einer temporären Datei als Hilfe gibt es eine Möglichkeit / ein Programm, das Eingaben puffern könnte, stdinaber den Inhalt erst ausgibt, wenn die EOF. Ich möchte auch keine Shell-Variable verwenden (zB buffer=$(cat)).

Dieses Programm sollte sich wie folgt verhalten (vorausgesetzt, der Programmname lautet buffered-cat):

$ buffered-cat
line 1
line 2
line 3
^D # Ctr-D here(End of Line)

Nachdem das Programm empfangen wurde ^D, buffered-catgibt es den Inhalt aus

line 1
line 2
line 3
Ekeyme Mo.
quelle
Ich benutze normalerweise sortfür diesen Zweck. Offensichtlich hat es Nebenwirkungen, die unerwünscht sein können.
Adrian Pronk

Antworten:

19

Ein armer Mann spongebenutzt awk:

awk '{a[NR] = $0} END {for (i = 1; i <= NR; i++) print a[i]}'

Wenn tacja, können Sie es auch missbrauchen:

... | tac | tac
muru
quelle
1
tacist einfach und elegant, denke ich.
Ekeyme Mo
6
@EkeymeMo | tac | tac ist einfach, aber denken Sie daran, dass es für die Aufgabe sehr ineffizient ist und Sie einen Leistungseinbruch erleiden, insbesondere bei größeren Dateien.
Digitales Trauma
@ DigitalTrauma Ja, ich kenne den Nachteil davon. Ich teste eine Datei, die mit 100 Tausend Zeilen. Für mich ist das in Ordnung. Ich habe Ihren Kommentar als wahr eingestuft.
Ekeyme Mo
29

Sie können dies mit spongemoreutils tun . spongewird "Standardeingabe aufsaugen und in eine Datei schreiben". Ohne Argumente ist diese Datei die Standardausgabe. Die Eingabe für diesen Befehl wird bis EOF gespeichert und dann auf einmal ausgeschrieben.

Zum Schreiben in eine normale Datei können Sie einfach den Dateinamen angeben:

cmd | sponge filename

Der Hauptzweck von spongebesteht darin, das Lesen und Schreiben aus derselben Datei innerhalb einer Pipeline zu ermöglichen, aber es macht auch das, was Sie wollen.

Michael Homer
quelle
6

Solange Ihre Eingabe ASCII-Text ist (enthält bis zum Ende keine NUL 0x0-Bytes), tun sed -zSie, was Sie wollen:

$ sed -z ''
Line 1
Line 2
Line 3
^D
Line 1
Line 2
Line 3
$ 

Die -zUrsachen sedfür die Behandlung des NUL-Bytes als Zeilenbegrenzer anstelle der üblichen neuen Zeile. Solange Ihre Eingabe regulärer Text ohne NUL-Bytes ist, liest sed die gesamte Eingabe weiter in ihren Musterpuffer, bis EOF erreicht ist. sedführt dann keine Verarbeitung des Puffers durch und gibt ihn aus.


Wenn Ihre Eingabe NUL-Bytes enthält, können Sie stattdessen Folgendes tun:

sed ':l;N;bl'
Digitales Trauma
quelle
4

Diese sedLösung ist etwas länger als die von DigitalTrauma, funktioniert aber auch mit NUL-Bytes.

sed -n 'H;${x;s/^\n//;p}'
JoL
quelle
2
sed ':l;N;bl'sollte auch funktionieren.
Digitales Trauma
1

Das Verhalten, nach dem Sie fragen, ist es nicht das Standardverhalten einer einfachen Katze?

gv@debian:$ cat << EOF #or cat <<EOF >file or cat <<EOF >/dev/stdout
> Line 1
> Line 2
> Line 3
> EOF
Line 1
Line 2
Line 3
gv@debian:$
George Vasiliou
quelle
3
Nein, das ist das Verhalten dieser Dokumente. catGeben Sie (Enter) Line 1(Enter) ein und sehen Sie, was passiert.
G-Man sagt "Reinstate Monica"
Ja, das ist hier-doc Struktur. Einfach und kommt dem, was OP will, ziemlich nahe. Erfordert auch keine Installation
Sergiy Kolodyazhnyy
1

Gleiche Idee wie Murus awk-Beispiel, außer in Python. Verwenden Sie CtrlDdiese Option , um das Lesen von Zeilen zu beenden

$ python -c 'import sys;print("".join(sys.stdin.readlines()))'                                                           
line1
line2
line3 # press Enter and Ctrl+D at this point
line1
line2
line3
Sergiy Kolodyazhnyy
quelle
2
Oder perl -e 'print <>'(!)
dave_thompson_085