filename dashed unix shell awk

unix - dashed filename



¿Existe una utilidad Unix para anteponer las marcas de tiempo a stdin? (17)

Terminé escribiendo un pequeño guión rápido para esto en Python, pero me preguntaba si había una utilidad en la que pudiera alimentar el texto que precedería a cada línea con texto, en mi caso específico, una marca de tiempo. Idealmente, el uso sería algo así como:

cat somefile.txt | prepend-timestamp

(Antes de responder a sed, intenté esto:

cat somefile.txt | sed "s/^/`date`/"

Pero eso solo evalúa el comando de fecha una vez cuando se ejecuta sed, por lo que la misma marca de tiempo se antepone incorrectamente a cada línea).


$ cat somefile.txt | sed "s/^/`date`/"

puedes hacer esto (con gnu / sed ):

$ some-command | sed "x;s/.*/date +%T/e;G;s//n/ /g"

ejemplo:

$ { echo ''line1''; sleep 2; echo ''line2''; } | sed "x;s/.*/date +%T/e;G;s//n/ /g" 20:24:22 line1 20:24:24 line2

por supuesto, puede usar otras opciones de la fecha del programa. simplemente reemplace la date +%T con lo que necesita.


¿Qué tal esto?

cat somefile.txt | perl -pne ''print scalar(localtime()), " ";''

A juzgar por su deseo de obtener marcas de tiempo en vivo, ¿tal vez desea actualizar en vivo en un archivo de registro o algo así? Tal vez

tail -f /path/to/log | perl -pne ''print scalar(localtime()), " ";'' > /path/to/log-with-timestamps


Aquí está mi solución awk (desde un sistema Windows / XP con MKS Tools instalado en el directorio C: / bin). Está diseñado para agregar la fecha y la hora actuales en el formato mm / dd hh: mm al comienzo de cada línea que ha obtenido esa marca de tiempo del sistema a medida que se lee cada línea. Por supuesto, podría usar el patrón BEGIN para obtener la marca de tiempo una vez y agregar esa marca de tiempo a cada registro (de todos modos). Hice esto para etiquetar un archivo de registro que se estaba generando para stdout con la marca de tiempo en el momento en que se generó el mensaje de registro.

/"pattern"/ "C/:////bin////date ''+%m/%d %R''" | getline timestamp;
print timestamp, $0;

donde "patrón" es una cadena o expresiones regulares (sin las comillas) para coincidir en la línea de entrada, y es opcional si desea hacer coincidir todas las líneas de entrada.

Esto debería funcionar también en sistemas Linux / UNIX, simplemente deshazte de C /: // bin // dejando la línea

"date ''+%m/%d %R''" | getline timestamp;

Esto, por supuesto, asume que el comando "fecha" le lleva al comando estándar mostrar / configurar fecha de Linux / UNIX sin información de ruta específica (es decir, la variable PATH de su entorno está configurada correctamente).


Destilando las respuestas dadas a la más simple posible:

unbuffer $COMMAND | ts

En Ubuntu, provienen de los paquetes expect-dev y moreutils.

sudo apt-get install expect-dev moreutils


La respuesta de Kieron es la mejor hasta ahora. Si tiene problemas porque el primer programa está guardando el búfer, puede usar el programa de eliminación de buffer:

unbuffer <command> | awk ''{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }''

Está instalado por defecto en la mayoría de los sistemas Linux. Si necesita construirlo usted mismo, es parte del paquete esperado

http://expect.nist.gov


La respuesta de caerwyn se puede ejecutar como una subrutina, lo que evitaría los nuevos procesos por línea:

timestamp(){ while read line do echo `date` $line done } echo testing 123 |timestamp


Mezclando algunas respuestas arriba de natevw y Frank Ch. Eigler.

Tiene milisegundos, funciona mejor que llamar a un comando de date externo cada vez y se puede encontrar perl en la mayoría de los servidores.

tail -f log | perl -pne '' use Time::HiRes (gettimeofday); use POSIX qw(strftime); ($s,$ms) = gettimeofday(); print strftime "%Y-%m-%dT%H:%M:%S+$ms ", gmtime($s); ''

Versión alternativa con descarga y lectura en bucle:

tail -f log | perl -pne '' use Time::HiRes (gettimeofday); use POSIX qw(strftime); $|=1; while(<>) { ($s,$ms) = gettimeofday(); print strftime "%Y-%m-%dT%H:%M:%S+$ms $_", gmtime($s); }''


No soy un chico de Unix, pero creo que puedes usar

gawk ''{print strftime("%d/%m/%y",systime()) $0 }'' < somefile.txt


Podría intentar usar awk :

<command> | awk ''{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush(); }''

Es posible que deba asegurarse de que <command> produzca salida de buffer de línea, es decir, vacíe su flujo de salida después de cada línea; la marca de tiempo awk agrega será el tiempo que el final de la línea apareció en su tubería de entrada.

Si awk muestra errores, prueba con gawk .


Si el valor que está anteponiendo es el mismo en cada línea, encienda emacs con el archivo, luego:

Ctrl + <espacio>

al principio del archivo (para marcar ese punto), desplácese hacia abajo hasta el comienzo de la última línea (Alt +> irá al final del archivo ... que probablemente también involucrará la tecla Shift, luego Ctrl + a para ir al comienzo de esa línea) y:

Ctrl + x r t

Cuál es el comando para insertar en el rectángulo que acaba de especificar (un rectángulo de ancho 0).

2008-8-21 6:45 PM <entrar>

O lo que sea que quieras anteponer ... entonces verás ese texto antepuesto a cada línea dentro del rectángulo de ancho 0.

ACTUALIZACIÓN: Me acabo de dar cuenta de que no quieres la MISMA fecha, así que esto no funcionará ... aunque puedes hacer esto en emacs con una macro personalizada un poco más complicada, pero aún así, este tipo de edición de rectángulo es bastante bueno saber sobre ...



Utilice el comando de lectura (1) para leer una línea a la vez de la entrada estándar, luego envíe la fecha antepuesta con la fecha en el formato de su elección usando la fecha (1).

$ cat timestamp #!/bin/sh while read line do echo `date` $line done $ cat somefile.txt | ./timestamp


haciéndolo con date y tr y xargs en OSX:

alias predate="xargs -I{} sh -c ''date +/"%Y-%m-%d %H:%M:%S/" | tr /"/n/" /" /"; echo /"{}/"''" <command> | predate

si quieres milisegundos:

alias predate="xargs -I{} sh -c ''date +/"%Y-%m-%d %H:%M:%S.%3N/" | tr /"/n/" /" /"; echo /"{}/"''"

pero tenga en cuenta que en OSX, la fecha no le da la opción% N, por lo que tendrá que instalar gdate ( brew install coreutils ) y finalmente llegar a esto:

alias predate="xargs -I{} sh -c ''gdate +/"%Y-%m-%d %H:%M:%S.%3N/" | tr /"/n/" /" /"; echo /"{}/"''"


annotate , disponible a través de ese enlace o como annotate-output en el paquete Debian devscripts .

$ echo -e "a/nb/nc" > lines $ annotate-output cat lines 17:00:47 I: Started cat lines 17:00:47 O: a 17:00:47 O: b 17:00:47 O: c 17:00:47 I: Finished with exitcode 0


ts de moreutils una marca de tiempo a cada línea de entrada que le des. Puedes formatearlo usando strftime también.

$ echo ''foo bar baz'' | ts Mar 21 18:07:28 foo bar baz $ echo ''blah blah blah'' | ts ''%F %T'' 2012-03-21 18:07:30 blah blah blah $

Para instalarlo:

sudo apt-get install moreutils


Descargo de responsabilidad : la solución que propongo no es una utilidad incorporada de Unix.

Me enfrenté a un problema similar hace unos días. No me gustó la sintaxis y las limitaciones de las soluciones anteriores, así que rápidamente armé un programa en Ir para hacer el trabajo por mí.

Puede consultar la herramienta aquí: preftime

Hay ejecutables precompilados para Linux, MacOS y Windows en la sección Releases del proyecto GitHub.

La herramienta maneja líneas de salida incompletas y tiene (desde mi punto de vista) una sintaxis más compacta.

<command> | preftime

No es ideal, pero pensé que lo compartiría en caso de que ayudara a alguien.


#! /bin/sh unbuffer "$@" | perl -e '' use Time::HiRes (gettimeofday); while(<>) { ($s,$ms) = gettimeofday(); print $s . "." . $ms . " " . $_; }''