2012-09-11 15 views
13

Mam następujący plik party.txt które zawierają coś jak następuje:Jak czerpać aktualną datę i czas i dołączyć na końcu każdej linii, które zawierają „Hello”

Hello Jacky 
Hello Peter 
Bye Johnson 
Hello Willy 
Bye Johnny 
Hello Mary 
Hello Wendy 

użyłem grep hello uchwycić zawierają, ale kiedy używam print date +"%Y-%m-%d' i dołączam do niego, nie mogę i otrzymam wiele 0 w linii.

cat party.txt | grep Hello | awk '{ print date +"%Y-%m-%d"}' 

Co mogłem być brakuje?

Odpowiedz

20

jedną stronę przy użyciu awk:

awk -v date="$(date +"%Y-%m-%d %r")" '/Hello/ { print $0, date}' party.txt 

Wyniki:

Hello Jacky 2012-09-11 07:55:51 PM 
Hello Peter 2012-09-11 07:55:51 PM 
Hello Willy 2012-09-11 07:55:51 PM 
Hello Mary 2012-09-11 07:55:51 PM 
Hello Wendy 2012-09-11 07:55:51 PM 
+0

W połączeniu z odpowiedzią danfuzz będzie prawie idealnie. – Jack

+2

Problem z tym rozwiązaniem polega na tym, że data jest ustawiona tylko jeden raz. jeśli masz plik (lub strumień), który zajmuje kilka sekund lub minut, aby parsować, każdy wpis będzie miał dokładnie tę samą datę/znacznik czasu. Również awk nie jest uniwersalnym poleceniem, które obsługuje -v, nawk. w systemie Solaris to nie zadziała, ale jeśli zastąpisz awk nawk, to zadziała, możesz również użyć gawk (zgodnej z POSIX/GNU). Preferuję odpowiedź Alina, która działa na wszystkich wersjach awk i systemach operacyjnych (pod warunkiem, że awk jest zamieniany na gawk). – Armand

2
awk 'BEGIN{"date +'%Y-%m-%d'"|getline d;}/Hello/{print $0,d}' file 

dadzą Ci:

Hello Jacky 2012-09-11 
Hello Peter 2012-09-11 
Hello Willy 2012-09-11 
Hello Mary 2012-09-11 
Hello Wendy 2012-09-11 
+0

W połączeniu z odpowiedzią danfuzz będzie prawie idealna. – Jack

2

Aby odpowiedzieć na bezpośrednie pytanie, co tracisz jest to date jest zewnętrzną komendą, więc musisz wywołać ją poza awk i przekazać jako zmienną (jak pokazuje jedna z pozostałych odpowiedzi), lub wywołać ją z poziomu awk jako polecenie systemowe albo przy użyciu architektury system(). in lub pipe (jak pokazuje inna z pozostałych odpowiedzi).

Powodem widać 0 dlatego wyrażenie date +"%Y-%m-%d" jest interpretowane jako dodając wartość numeryczną zmiennej date (który będzie 0 jak to nie jest zdefiniowane) na wartość numeryczną łańcucha "%Y-%m-%d" (który będzie 0 jako nie jest to prawidłowy numer).

+0

W połączeniu z odpowiedzią na steve lub kent, będzie prawie idealna. – Jack

31

Awk ma wbudowany time/date function, nie ma potrzeby korzystania z zewnętrznych narzędzi.

awk '/Hello/{print NR " - " $0 " - " strftime("%Y-%m-%d")}' party.txt 
+0

jedyną zmianą, którą chciałbym wprowadzić, jest zastąpienie awk gawk w systemach operacyjnych, gdzie awk nie jest zgodną z POSIX/GNU. Cóż, to i aby usunąć numer wiersza, który nie był częścią pierwotnego żądania. – Armand

0

Jeśli jesteś otwarty na użyciu Perl:

perl -MPOSIX -lne 'if (/Hello/){ print "$_ " . strftime "%Y-%m-%d",localtime }' party.txt 

produkuje to wyjście

Hello Jacky 2015-10-01 
Hello Peter 2015-10-01 
Hello Willy 2015-10-01 
Hello Mary 2015-10-01 
Hello Wendy 2015-10-01 

Oto jak to działa:

  • -n pętle wokół każdej linii pliku wejściowego, nie au tycznie wydrukować każdą linię

  • -l usuwa znaki nowej linii przed obróbką i dodaje je z powrotem w później

  • -e wykonać kod perla

  • $_ jest bieżąca linia

  • -MPOSIX ładuje POSIX moduł, który zawiera strftime

  • localtime i strftime drukuje czasu, ponieważ format %Y-%m-%d

0

pomocą POSIX sed (a podpowłoki powodu braku funkcji czasu w SED)

sed -n "/^Hello/ s/$/ $(date +'%Y-%m-%d')/p" party.txt 

powrotnej

Hello Jacky 2016-11-10 
Hello Peter 2016-11-10 
Hello Willy 2016-11-10 
Hello Mary 2016-11-10 
Hello Wendy 2016-11-10 
1

To rozwiązanie powinno działać z każdym awk:

awk '/Hello/ {cmd="(date +'%H:%M:%S')"; cmd | getline d; print d,$0; close(cmd)}' party.txt 

Magia dzieje się w oświadczeniu close(cmd). Wymusza to, aby awk wykonywał za każdym razem cmd, więc za każdym razem data byłaby aktualna.

odczytuje wyjście z cmd i zapisuje je na d.

Powiązane problemy