Umieść tekst przed każdą nową linią, którą program wypisuje na standardowe wyjście

9

Więc chcę zrobić rejestrowanie i dlatego chcę umieścić datę przed wyjściem skryptu bash. Problem polega na tym, że ma wiele linii wyjściowych. Jestem w stanie umieścić datę tylko przed całym wyjściem. Ale potem w dziennikach mam wiersz bez daty. Oczywiście mogę założyć, że data z powyższej linii jest taka sama, ale miałem nadzieję, że istnieje rozwiązanie. Z góry dziękuję!

To jest mój skrypt, który wywołuje inny skrypt:

#!/bin/sh
echo $(date "+%F %T") : starting script
echo $(date "+%F %T") : $(./script.sh)
echo $(date "+%F %T") :script ended

To jest wynik:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
second line of output
2012-07-26 15:35:17 : script ended

I właśnie to chciałbym mieć:

2012-07-26 15:34:12 : starting script
2012-07-26 15:35:14 : First line of output
2012-07-26 15:35:15 : second line of output
2012-07-26 15:35:17 : script ended
tzippy
źródło
Nie sądzę, żebyś mógł po prostu zmienić drugi skrypt?
jmetz
Nie, niestety nie. Dlatego tu przyszedłem.
tzippy

Odpowiedzi:

3

Myślę, że możesz użyć do tego awk:

./script.sh | awk '{ print strftime()" : "$0; }'

(zobacz http://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html w celu sformatowania daty zwróconej przez strftime ())

Flinth
źródło
2
awk: calling undefined function strftime- czy to jest specyficzne gawk?
Daniel Beck
Teraz, kiedy o tym wspominasz, wydaje się, że tak: /
Flinth
2

Możesz użyć awk

./script.sh | awk '{ print d,$1}' "d=$(date "+%F %T")"

awkpobiera strumień wejściowy i modyfikuje jego wynik. Skrypt mówi „drukuj d po oryginalnym wydruku”, a następnie zapełnia dsię datą.

Paweł
źródło
1
Czy to nie ocenia datewyrażenia również tylko raz, aby wszystkie takie linie były drukowane w tym samym czasie?
Daniel Beck
@DanielBeck Tak, tak - założyłem, że za każdym razem zbiera datę, ale dość szybko ukończyłem test
Paul
1

Spowoduje to wydrukowanie bieżącej daty i godziny przed każdym wierszem danych wyjściowych ./script.sh:

set -f
./script.sh | while read -r LINE; do echo $(date "+%F %T") : "$LINE"; done
set +f

Jak to działa

  • set -fwyłącza rozszerzenie bash (lub echo *nie drukuje rzeczywistej gwiazdki).

  • while read -r LINE; do ... donezapisuje jeden wiersz wyniku w zmiennej $LINEi wykonuje ..., dopóki wszystkie wiersze nie zostaną przetworzone.

  • echo $ (data „+% F% T”): „$ LINE” drukuje linię z bieżącą godziną i datą.

  • set +f ponownie włącza rozszerzenie bash, aby nie zakłócało reszty skryptu bash.

Dennis
źródło
Jest oceniany tylko raz, więc każdy sedwstawia tę samą datę, tuż przed rozpoczęciem drugiego skryptu. Prawdopodobnie nie to, czego chce użytkownik ...
Daniel Beck
Nie sądzę też, żeby ta próba zadziałała. AFAIK, cała podpowłoka jest najpierw oceniana całkowicie, a następnie przechodzi pętla. Więc teraz czasy są od po egzekucji.
Daniel Beck
Twój przykład nie działa, ponieważ opóźniasz tylko wyjście, a nie wykonanie ls. Po prostu wypróbuj swój skrypt w następujący sposób script.sh: #!/bin/bash(nowa linia)echo 1 ; sleep 1 ; echo 2 ; sleep 2 ; echo 3 ; sleep 3 ; echo 4
Daniel Beck
Użyj readz whilepętlą zamiast z pętlą for.
chepner
@chepner: Dobry pomysł.
Dennis