2012-09-11 23 views
13

tengo el archivo siguiente party.txt que contiene algo como lo siguiente:cómo derivar fecha y hora actuales y añadir al final de cada línea que contiene 'Hola'

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

he utilizado la grep hello para capturar la contener pero cuando uso el print date +"%Y-%m-%d' y anexo a él, no puedo y obtendré muchos 0 por línea.

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

¿Qué podría estar perdiendo?

Respuesta

20

Una forma en que el uso de awk:

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

Resultados:

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

Si se combina con la respuesta de danfuzz, sería casi perfecto. – Jack

+2

El problema que tengo con esta solución es que la fecha se establece una vez. si tiene un archivo (o secuencia) que tarda varios segundos o minutos en analizar, cada entrada tendrá exactamente la misma fecha/hora. También awk no es el comando universal que admite -v, nawk es. en Solaris, esto no funcionará, pero si reemplaza awk con nawk, funcionará, también podría usar gawk (la versión compatible con POSIX/GNU). Prefiero la respuesta de Alin que funciona en todas las implementaciones awk y sistemas operativos (siempre que awk sea reemplazado por gawk) – Armand

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

os haré:

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

Si se combina con la respuesta de danfuzz, sería casi perfecto. – Jack

2

Para responder a la pregunta directa, lo que se pierde es que date es un comando externo, por lo que necesita invocarlo fuera de awk y pasarlo como una variable (como lo demuestra una de las otras respuestas), o invocarlo desde awk como un comando del sistema, ya sea utilizando el system() integrado. en o una tubería (como lo demuestra otra de las otras respuestas).

La razón por la que se ve 0 se debe a la expresión date +"%Y-%m-%d" se interpreta como añadir el valor numérico de la variable date (que será 0 ya que no está definido) al valor numérico de la cadena "%Y-%m-%d" (que será 0 como no es un número válido).

+0

Si se combina con la respuesta steve o kent, sería casi perfecto. – Jack

31

Awk tiene incorporado time/date function, no es necesario utilizar herramientas externas.

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

el único cambio que haría es reemplazar awk con gawk en los sistemas operativos donde awk no es la versión compatible con POSIX/GNU. Bueno, eso y para eliminar el número de línea que no era parte de la solicitud original. – Armand

0

Si usted está abierto a la utilización de Perl:

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

produce esta salida

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 

Así es como funciona:

  • -n bucles en cada línea del archivo de entrada, no au ticamente imprimir cada línea

  • -l elimina los saltos de línea antes de la transformación, y los añade de nuevo en después

  • -e ejecutar el código Perl

  • $_ es la línea actual

  • -MPOSIX cargas del POSIX módulo, que incluye strftime

  • localtime y strftime imprime el tiempo, dado el formato %Y-%m-%d

0

usando posix sed (y un sub shell debido a la falta de función de tiempo en SED)

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

retorno

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

Esta solución debería funcionar con cualquier awk:

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

La magia ocurre en la declaración close(cmd). Fuerza awk para ejecutar cmd cada vez, por lo que la fecha sería real una vez cada vez.

cmd | get line d lee la salida desde cmd y la guarda en d.

Cuestiones relacionadas