2012-09-11 13 views
13

ho il seguente file party.txt che contengono qualcosa di simile al seguente:Come ricavare la data e l'ora correnti e aggiungere alla fine di ogni riga che contiene 'Ciao'

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

ho usato il grep hello per catturare il contenere ma quando uso il print date +"%Y-%m-%d' e aggiungo ad esso, non posso e otterrò molti 0 per riga.

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

Cosa potevo mancare?

risposta

20

One way utilizzando awk:

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

Risultati:

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

Se si combinano con la risposta di danfuzz, sarebbe quasi perfetto. – Jack

+2

Il problema che ho con questa soluzione è che la data viene impostata una volta. se si dispone di un file (o flusso) che richiede diversi secondi o minuti per essere analizzato, ogni voce avrà lo stesso indicatore di data/ora. Inoltre awk non è il comando universale che supporta -v, nawk è. su Solaris, questo non funzionerà, ma se sostituisci awk con nawk, funzionerà, potresti anche usare gawk (la versione compatibile con POSIX/GNU). Preferisco la risposta di Alin che funziona su tutte le implementazioni e sistemi operativi di awk (a patto che awk sia sostituito da gawk) – Armand

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

offrono:

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

Se combinato con la risposta di danfuzz, sarebbe quasi perfetto. – Jack

2

Per rispondere alla domanda diretta, cosa ti perdi è quello date è un comando esterno, quindi è necessario richiamarlo all'esterno di awk e passarlo come variabile (come dimostra una delle altre risposte), oppure richiamarlo dall'interno di awk come comando di sistema usando l'architettura system() in o una pipe (come dimostra un'altra delle altre risposte).

La ragione si vede 0 è perché l'espressione date +"%Y-%m-%d" viene interpretata come aggiungendo il valore numerico della variabile date (che sarà 0 come non è definito) al valore numerico della stringa "%Y-%m-%d" (che sarà 0 come non è un numero valido).

+0

Se combinate con una risposta steve o kent, sarebbe quasi perfetto. – Jack

31

Awk ha incorporato time/date function, non è necessario utilizzare strumenti esterni.

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

l'unica modifica che farei è sostituire awk con gawk su sistemi operativi in ​​cui awk non è la versione compatibile con POSIX/GNU. Bene, quello e per rimuovere il numero di linea che non faceva parte della richiesta originale. – Armand

0

Se siete aperti ad usare Perl:

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

produce questa uscita Funziona così

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 

Qui:

  • -n loop dietro ogni linea del file di input, non au tomaticamente stampare ogni linea

  • -l rimuove a capo prima della lavorazione, e li aggiunge nel seguito

  • -e eseguire il codice Perl

  • $_ è la linea corrente

  • -MPOSIX carichi il POSIX modulo, che include strftime

  • localtime e strftime stampa il tempo, data la disposizione %Y-%m-%d

0

utilizzando posix sed (ed un guscio sub dovuto alla funzione di tempo mancante in sed)

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

ritorno

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

Questa soluzione dovrebbe funzionare con qualsiasi awk:

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

La magia si verifica nell'istruzione close(cmd). Costringe awk ad eseguire ogni volta cmd, quindi la data sarà effettiva ogni volta.

cmd | get line d legge l'output da cmd e lo salva in d.

Problemi correlati