cat <<EOS | sed -ne '1{h;d;}' -e 'H;${G;p;}'
line 1
line 2
line 3
EOS
Problem z przetłumaczeniem tego na coś, co używa, tailpolega na tym, że tailtrzeba przeczytać cały plik, aby znaleźć jego koniec. Aby użyć tego w potoku, musisz
- Podaj pełną treść dokumentu do
tail.
- Dostarczenie go ponownie do
cat.
- W tej kolejności.
Problem polega na tym, aby nie powielać zawartości dokumentu ( teerobi to), ale uzyskać wynik, tailktóry ma się wydarzyć przed wydrukowaniem pozostałej części dokumentu, bez użycia pośredniego pliku tymczasowego.
Używanie sed(lub awk, jak John1024 ) eliminuje podwójne analizowanie danych i problem z porządkowaniem poprzez przechowywanie danych w pamięci.
sedRozwiązania, które jest zaproponowanie
1{h;d;}, zapisz pierwszy wiersz w niezatrzymanym miejscu i przejdź do następnego.
H, dodajcie sobie nawzajem linię do miejsca wstrzymania za pomocą osadzonej nowej linii.
${G;p;}, dodaj przestrzeń wstrzymania do ostatniego wiersza z osadzoną nową linią i wydrukuj uzyskane dane.
Jest to dosłowne tłumaczenie rozwiązania John1024 na sed, z zastrzeżeniem, że standard POSIX gwarantuje tylko, że przestrzeń wstrzymania wynosi co najmniej 8192 bajtów (8 KiB; ale zaleca, aby bufor ten był dynamicznie przydzielany i rozszerzany w razie potrzeby, które to oba GNU sedi BSD sedrobi).
Jeśli pozwolisz sobie na użycie nazwanego potoku:
mkfifo mypipe
cat <<EOS | tee mypipe | cat <( tail -n 1 mypipe ) -
line 1
line 2
line 3
EOS
rm -f mypipe
Służy teedo wysyłania danych w dół mypipei jednocześnie do cat. catNarzędzie najpierw odczytać dane wyjściowe tail(który odczytuje z mypipe, co teepisze się), a następnie dołączyć kopię dokumentu pochodzącego bezpośrednio z tee.
Jest w tym jednak poważna wada, polegająca na tym, że jeśli dokument jest zbyt duży (większy niż rozmiar bufora potoku), teezapisuje mypipei catblokuje się podczas oczekiwania na opróżnienie (nienazwanego) potoku. Nie zostanie opróżniony, dopóki się catz niego nie przeczyta. catnie czytałby z niego, dopóki się tailnie skończy. I tailnie skończy, dopóki się teenie skończy. Jest to klasyczny impas.
Wariacja
tee >( tail -n 1 >mypipe ) | cat mypipe -
ma ten sam problem.