Przygotowuję prezentację dla nietechnicznych odbiorców. Mam program działający w trybie bash, który generuje ciągły strumień wartości, z których kilka jest ważnych. Chciałbym podkreślić ważne wyniki podczas ich wyświetlania, aby publiczność mogła dowiedzieć się o ich częstotliwości. Problem polega na tym, że nie mogę sed
uruchomić działającego strumienia. Działa dobrze, jeśli umieszczę wyniki w pliku, jak w:
cat output.txt | sed "s/some text/some text bolded/"
Ale jeśli spróbuję tego samego na uruchomionym wyjściu, to tak:
command | sed "s/some text/some text bolded/"
sed
nic nie robi. jakieś pomysły?
Jak Lambert był na tyle pomocny, by to podkreślić, moje powiedzenie, że sed
nic nie robi, było niejasne. To, co się dzieje, polega na tym, że program wypisuje stdout
(jestem pewien, że nie pisze do stderr
), jak zwykle, nawet jeśli jest przesyłany strumieniowo sed
.
Problem polega na tym, że polecenie wywołuje drugi program, który następnie wyprowadza na standardowe wyjście. Pierwszy program drukuje kilka wierszy; te mogę edytować. Następnie jest strumień wartości drukowany przez drugi program; tych nie mogę edytować.
Metody Perl i awk również nie działają.
źródło
stdbuf -o0 command | sed "s/some text/some text bolded/"
działacommand|egrep 'some text|$'
g
„globalne” podstawienie, w przeciwnym razie zostanie zastąpione tylko pierwsze wystąpienie w wierszu:sed "s/old/new/g"
Odpowiedzi:
Możliwe, że dane wyjściowe polecenia są buforowane. Kiedy polecenie zapisuje na terminalu, bufor jest opróżniany przy każdej nowej linii, więc widać, że pojawia się w oczekiwanym tempie. Kiedy polecenie zapisuje do potoku, bufor jest opróżniany tylko wtedy, gdy osiągnie kilka kilobajtów, więc jest bardzo opóźniony. Tak jest domyślne zachowanie standardowej biblioteki wejścia / wyjścia.
Aby zmusić polecenie, aby nie buforowało wyników, możesz użyć
unbuffer
(z oczekiwań) lubstdbuf
(z GNU coreutils).źródło
stdbuf
nie działało (wcześniej wspomniano, BTW), ale działałounbuffer
!! Nie masz pojęcia, jak mnie uszczęśliwiłeś.sed
Sam używa takiego bufora, (por ChennyStar post) Tak tu przykłady nie może działać, ponieważsed
jestcommand
do unbuffer:cat /etc/passwd | unbuffer sed
alesed
sama ma-u
opcji, więcgrep
może być bardziej Skuteczny w tych przykładach. Wielkie dzięki za informacje w tle! Świetna odpowiedź!sed
ma na to opcję:Który ładuje minimalne ilości danych z plików wejściowych i częściej opróżnia bufory wyjściowe. Zobacz
man sed
po więcej szczegółów.źródło
sed
Tylko GNU (nie BSDsed
) i uważam, że nadal nie zapobiegałoby to buforowaniu polecenia na początku potoku. Ale dobrze o tym wspomnieć. :)Użyłbym awk
gdzie
/some important stuff/
wybierz ważną linię, jak w sedprintf "%c[31m%s%c[0m\n",27,$0,27 ;
drukuj na czerwonokluczową kwestią jest to, że
command
powinny wypłukać linie, ale tak powinno być, jeśli masz dużo wyników.źródło
awk
(za pomocąsub()
lubgsub()
), w przypadku tej prymitywnej substytucjised
jest z pewnością odpowiednim narzędziem.The Perl Way:
lub z ciągłą wydajnością:
Skrypt bash dla wyniku
cont
:Testuj z:
\x1b[1m
- pogrubienie lub zwiększenie intensywności${1}
- backreferenze\x1b[0m
- zresetuj wszystkie atrybutyWynik:
Więcej kodów ucieczki tutaj .
źródło