Skończyło się na napisaniu krótkiego skryptu do tego w Pythonie, ale zastanawiałem się, czy istnieje narzędzie, do którego można by wprowadzić tekst, które poprzedzałoby każdą linię jakimś tekstem - w moim przypadku znacznikiem czasu. Idealnie byłoby użyć czegoś takiego:
cat somefile.txt | prepend-timestamp
(Zanim odpowiesz sed, próbowałem tego:
cat somefile.txt | sed "s/^/`date`/"
Ale to oblicza datę tylko raz, gdy sed jest wykonywane, więc ten sam znacznik czasu jest niepoprawnie dodawany do każdej linii.)
cat somefile.txt
to trochę „mylące”? Spodziewałbym się, że stanie się to „od razu” i będzie miało jeden znacznik czasu. Czy nie byłoby to lepsze program testowy:(echo a; sleep 1; echo b; sleep 3; echo c; sleep 2)
?Odpowiedzi:
Możesz spróbować użyć
awk
:Być może będziesz musiał się upewnić, że
<command>
wytwarza buforowane liniowo wyjście, tj. Opróżnia swój strumień wyjściowy po każdej linii;awk
dodanie znacznika czasu będzie oznaczało czas pojawienia się końca linii na potoku wejściowym.Jeśli awk wyświetla błędy, spróbuj
gawk
zamiast tego.źródło
gawk
i używać tego zamiastawk
. Jeśli masz MacPorts:sudo port install gawk
awk
nicstrftime()
nie ma milisekundy precyzji. Możesz jednak użyćdate
polecenia. Zasadniczo po prostu przycinasz nanosekundy do trzech znaków. Będzie to wyglądać tak:COMMAND | while read -r line; do echo "$(date '+%Y-%m-%d %T.%3N') $line"; done
. Zauważ, że możesz skrócić% H:% M:% S za pomocą% T. Jeśliawk
z jakiegoś powodu nadal chcesz korzystać , możesz wykonać następujące czynności:COMMAND | awk '{ "date +%Y-%m-%d\\ %T.%3N" | getline timestamp; print timestamp, $0; fflush(); }'
ts
z moreutils doda znacznik czasu do każdego wprowadzonego wiersza. Możesz go również sformatować za pomocą strftime.Aby go zainstalować:
źródło
bad command 2>&1 | ts
wyniki wJan 29 19:58:31 -bash: bad: command not found
2014 Mar 21 18:07:28
. Jak mogę to dostać?strftime
jako argument podaj ciąg formatu:[.. command ..] | ts '%Y %b %d %T'
na przykład.brew install moreutils
. Aby wyświetlić UTC, możesz ustawić TZ lokalnie, np.ls -l |TZ=UTC ts '%Y-%m-%dT%H:%M:%SZ'
ruby -e "puts 1; STDOUT.flush; sleep 1; puts 2; STDOUT.flush; sleep 2; puts 3" | ts '%F %T'
adnotate , dostępne pod tym linkiem lub jak
annotate-output
wdevscripts
pakiecie Debiana .źródło
Podane odpowiedzi destylujemy do najprostszej możliwej:
W Ubuntu pochodzą one z pakietów Expect-dev i moreutils.
źródło
expect
nie jestexpect-dev
, ale ta druga wciąga pierwszą, więc to działa. (Ubuntu 14.10, zastanawiam się, czy plik binarny został kiedyś przeniesiony do innego pakietu.)expect-dev
unbuffer $COMMAND | ts -s %.s
(-s
jeśli dla czasu, który upłynął i%.s
dla czasu w sekundach z częścią ułamkową)Co powiesz na to?
Sądząc po chęci uzyskania znaczników czasu na żywo, może chcesz aktualizować na żywo plik dziennika lub coś takiego? Może
źródło
tail -f /path/to/log | perl -pne 'use POSIX qw(strftime); print strftime "%Y-%m-%dT%H:%M:%SZ ", gmtime();'
otrzymywałem datę w stylu ISO8601 / RFC3339 zamiast wacko, którą daje prostsza wersja.BEGIN { $|++; }
przed instrukcją print, aby Perl opróżniał swoje wyjście z każdą linią.ls | perl -pne 'print localtime." "'
. Konwersja skalarna następuje w wyniku konkatenacji ciągów.-p
i-n
? Wydaje się, że-n
jest zbędny, jeśli określiłeś-p
.Po prostu wyrzucę to: w narzędziach daemontools o nazwach tai64n i tai64nlocal są stworzone do dodawania znaczników czasu do dziennika komunikatów.
Przykład:
źródło
Odpowiedź Kierona jest jak dotąd najlepsza. Jeśli masz problemy, ponieważ pierwszy program buforuje swoje dane, możesz użyć programu niebuforującego:
Jest instalowany domyślnie w większości systemów linuxowych. Jeśli chcesz zbudować go samodzielnie, jest to część pakietu oczekującego
http://expect.nist.gov
źródło
Użyj polecenia read (1), aby odczytać po jednym wierszu na raz ze standardowego wejścia, a następnie wypisz wiersz poprzedzony datą w wybranym przez siebie formacie przy użyciu daty (1).
źródło
Nie jestem facetem od Uniksa, ale myślę, że możesz użyć
źródło
źródło
Oto moje rozwiązanie awk (z systemu Windows / XP z narzędziami MKS zainstalowanymi w katalogu C: \ bin). Jest przeznaczony do dodawania aktualnej daty i czasu w postaci mm / dd gg: mm na początku każdego wiersza po pobraniu tego znacznika czasu z systemu podczas odczytywania każdego wiersza. Możesz oczywiście użyć wzorca BEGIN, aby raz pobrać znacznik czasu i dodać go do każdego rekordu (tak samo). Zrobiłem to, aby oznaczyć plik dziennika, który był generowany na stdout, znacznikiem czasu w momencie generowania komunikatu dziennika.
/"pattern"/ "C\:\\\\bin\\\\date '+%m/%d %R'" | getline timestamp;
print timestamp, $0;
gdzie „wzorzec” jest ciągiem lub wyrażeniem regularnym (bez cudzysłowów) do dopasowania w wierszu wejściowym i jest opcjonalne, jeśli chcesz dopasować wszystkie wiersze wejściowe.
Powinno to działać również w systemach Linux / UNIX, po prostu pozbądź się C \: \\ bin \\ opuszczającego linię
Zakłada to oczywiście, że polecenie „date” prowadzi do standardowego polecenia wyświetlania / ustawiania daty w systemie Linux / UNIX bez określonych informacji o ścieżce (to znaczy, że zmienna środowiska PATH jest poprawnie skonfigurowana).
źródło
Połączenie kilku powyższych odpowiedzi od natevw i Franka Ch. Eigler.
Ma milisekundy, działa lepiej niż wywoływanie zewnętrznej
date
komendy za każdym razem, a perl można znaleźć na większości serwerów.Alternatywna wersja z opróżnieniem i odczytem w pętli:
źródło
printf "%s+%06d %s", (strftime "%Y-%m-%dT%H:%M:%S", gmtime($s)), $ms, $_;
możesz to zrobić (z gnu / sed ):
przykład:
oczywiście możesz skorzystać z innych opcji daty programu . po prostu zastąp
date +%T
to, czego potrzebujesz.źródło
Odpowiedź caerwyn może zostać uruchomiona jako podprocedura, która uniemożliwiłaby nowe procesy w linii:
źródło
date
się w każdej linii?timestamp() { while read line; do echo "$(date) $line"; done; }; export -f timestamp
w skrypcie, którego źródła.date
w każdej linii, spróbuj użyćprintf
wbudowanego bash z formatem % (datepec) T. Więc może to wyglądaćtimestamp() { while IFS= read -r line; do printf "%(%F %T)T %s\n" -1 "$line"; done; }
. Wbudowane powłoki nie pojawią się. Format Datespec jest podobny do formatówstrftime(3)
npdate
. Wymaga to basha, nie jestem pewien, od której wersji obsługuje tenprintf
specyfikator.Zastrzeżenie : rozwiązanie, które proponuję, nie jest narzędziem wbudowanym w system Unix.
Z podobnym problemem miałem do czynienia kilka dni temu. Nie podobała mi się składnia i ograniczenia powyższych rozwiązań, więc szybko złożyłem program w Go, aby wykonać zadanie za mnie.
Możesz sprawdzić narzędzie tutaj: preftime
W sekcji Wydania projektu GitHub znajdują się gotowe pliki wykonywalne dla systemów Linux, MacOS i Windows .
Narzędzie obsługuje niekompletne wiersze wyjściowe i ma (z mojego punktu widzenia) bardziej zwartą składnię.
<command> | preftime
To nie jest idealne, ale pomyślałem, że podzielę się nim na wypadek, gdyby to komuś pomogło.
źródło
robi to z
date
itr
axargs
na OSX:jeśli chcesz milisekund:
ale pamiętaj, że na OSX data nie daje opcji% N, więc musisz zainstalować gdate (
brew install coreutils
) i ostatecznie dojść do tego:źródło
Jeśli dodawana wartość jest taka sama w każdym wierszu, uruchom emacsa z plikiem, a następnie:
Ctrl + <space>
na początku pliku (aby zaznaczyć to miejsce), a następnie przewiń w dół do początku ostatniej linii (Alt +> przejdzie do końca pliku ... co prawdopodobnie będzie wymagało również naciśnięcia klawisza Shift, a następnie Ctrl + a, aby przejść na początek tego wiersza) i:
Ctrl + x r t
Które polecenie należy wstawić do właśnie określonego prostokąta (prostokąta o szerokości 0).
2008-8-21 18:45 <enter>
Lub cokolwiek chcesz dodać na początku ... wtedy zobaczysz ten tekst dołączony do każdego wiersza w prostokącie o szerokości 0.
AKTUALIZACJA: Właśnie zdałem sobie sprawę, że nie chcesz tej SAMEJ daty, więc to nie zadziała ... chociaż możesz być w stanie to zrobić w emacsie za pomocą nieco bardziej skomplikowanego niestandardowego makra, ale nadal ten rodzaj edycji prostokąta jest miło wiedzieć o ...
źródło