Program, który może buforować standardowe wejście lub plik

12

Oprócz korzystania z pliku tymczasowego do pomocy, czy istnieje sposób / program mógłby buforować dane wejściowe z, stdinale nie wysyła zawartości do momentu uzyskania EOF. Nie chcę też używać zmiennej powłoki (np buffer=$(cat).).

Ten program powinien zachowywać się jak poniżej (zakładając, że nazwa programu to buffered-cat):

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

Teraz, gdy program otrzymał ^D, buffered-catwyświetla zawartość

line 1
line 2
line 3
Ekeyme Mo
źródło
Zwykle używam sortdo tego celu. Oczywiście ma skutki uboczne, które mogą być niepożądane.
Adrian Pronk

Odpowiedzi:

20

Biedny człowiek spongeużywa awk:

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

Jeśli tak tac, możesz go również niewłaściwie użyć:

... | tac | tac
muru
źródło
1
tacmyślę, że jest prosty i elegancki.
Ekeyme Mo
6
@EkeymeMo | tac | tac jest prosty, ale należy pamiętać, że jest on bardzo nieefektywny dla zadania, a Ty odczujesz spadek wydajności, szczególnie w przypadku większych plików.
Cyfrowa trauma
@DigitalTrauma tak, znam wadę tego. Testuję plik z linią 100 tysięcy. Dla mnie ok. Głosowałem za waszym komentarzem, ponieważ to prawda.
Ekeyme Mo
29

Możesz to zrobić za pomocą spongemoreutils . sponge„wchłonie standardowe dane wejściowe i zapisze w pliku”. Bez argumentów plik ten jest standardowym wyjściem. Dane wejściowe podane dla tego polecenia są przechowywane w pamięci aż do EOF, a następnie zapisywane jednocześnie.

Aby zapisać do normalnego pliku, możesz po prostu podać nazwę pliku:

cmd | sponge filename

Głównym celem spongejest umożliwienie odczytu i zapisu z tego samego pliku w potoku, ale robi to, co chcesz.

Michael Homer
źródło
6

Tak długo, jak wpisujesz tekst ASCII (do końca nie zawiera bajtów NUL 0x0), wtedy sed -zrobi to, co chcesz:

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

Te -zprzyczyny sedtraktować bajt NUL jako ogranicznik linii zamiast zwykłego linią. Tak długo, jak twój tekst jest zwykłym tekstem bez bajtów NUL, wtedy sed będzie wczytywał cały tekst do bufora wzorców, aż do osiągnięcia EOF. sednastępnie nie przetwarza bufora i wysyła go.


Jeśli na wejściu znajdują się bajty NUL, możesz to zrobić w zamian:

sed ':l;N;bl'
Cyfrowa trauma
źródło
4

To sedrozwiązanie jest nieco dłuższe niż rozwiązanie DigitalTrauma, ale działa również z bajtami NUL.

sed -n 'H;${x;s/^\n//;p}'
JoL
źródło
2
sed ':l;N;bl'też powinien działać.
Cyfrowy uraz
1

Zachowanie, o które prosisz, czy nie jest to domyślne zachowanie zwykłego kota?

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
źródło
3
Nie, takie jest zachowanie tych dokumentów. Spróbuj wpisać cat(Enter) Line 1(Enter) i zobacz, co się stanie.
G-Man mówi „Przywróć Monikę”
Tak, to jest struktura doc tutaj. Prosty i zbliża się do tego, czego chce OP. Nie wymaga również instalacji
Sergiy Kolodyazhnyy
1

Taki sam pomysł jak w awk Muru, z wyjątkiem Pythona. Użyj, CtrlDaby zatrzymać czytanie w wierszach

$ 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
źródło
3
Lub perl -e 'print <>'(!)
dave_thompson_085