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

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

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.


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'

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}'

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:$

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

3
Lub perl -e 'print <>'(!)
dave_thompson_085
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.