unixtime - Existe um utilitário Unix para preceder timestamps para stdin?




unixtime stamp online (12)

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

você pode fazer isso (com o gnu / sed ):

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

exemplo:

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

Claro, você pode usar outras opções da data do programa. basta substituir date +%T pelo que você precisa.

Acabei escrevendo um pequeno script rápido para isso em Python, mas fiquei me perguntando se havia um utilitário no qual você pudesse inserir texto no qual precederia cada linha com algum texto - no meu caso específico, um timestamp. Idealmente, o uso seria algo como:

cat somefile.txt | prepend-timestamp

(Antes de responder sed, eu tentei isso:

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

Mas isso só avalia o comando date uma vez quando o sed é executado, então o mesmo timestamp é prefixado incorretamente para cada linha.)


A resposta de Kieron é a melhor até agora. Se você tiver problemas porque o primeiro programa está armazenando em buffer, você pode usar o programa unbuffer:

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

Ele é instalado por padrão na maioria dos sistemas Linux. Se você precisa construí-lo você faz parte do pacote expect

http://expect.nist.gov


Aqui está a minha solução awk (de um sistema Windows / XP com o MKS Tools instalado no diretório C: \ bin). Ele é projetado para adicionar a data e a hora atuais no formato mm / dd hh: mm ao início de cada linha, tendo obtido o registro de data e hora do sistema à medida que cada linha é lida. Você poderia, é claro, usar o padrão BEGIN para buscar o registro de data e hora uma vez e adicionar esse registro de data e hora a cada registro (tudo a mesma coisa). Fiz isso para marcar um arquivo de log que estava sendo gerado para stdout com o timestamp no momento em que a mensagem de log foi gerada.

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

onde "padrão" é uma string ou regex (sem as aspas) para ser correspondido na linha de entrada, e é opcional se você deseja combinar todas as linhas de entrada.

Isso deve funcionar em sistemas Linux / UNIX, apenas livrar-se do C \: \\ bin \\ deixando a linha

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

Isso, obviamente, pressupõe que o comando "date" leve você ao comando display / set de data padrão do Linux / UNIX sem informações de caminho específicas (ou seja, a variável PATH do ambiente está configurada corretamente).


Destilando as respostas dadas ao mais simples possível:

unbuffer $COMMAND | ts

No Ubuntu, eles vêm dos pacotes expect-dev e moreutils.

sudo apt-get install expect-dev moreutils

Misturando algumas respostas acima de natevw e Frank Ch. Eigler

Ele tem milissegundos, funciona melhor do que chamar um comando de date externa toda vez e o perl pode ser encontrado na maioria dos 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);
  '

Versão alternativa com flush e leitura em loop:

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);
  }'

Poderia tentar usar o awk :

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

Pode ser necessário certificar-se de que <command> produz saída de buffer de linha, isto é, libera seu fluxo de saída após cada linha; o timestamp awk adds será o tempo que o final da linha apareceu em seu pipe de entrada.

Se o awk mostrar erros, tente o gawk .


Só vou jogar isso lá fora: há um par de utilitários nos daemontools chamados tai64n e tai64nlocal que são feitos para tai64nlocal adicionar os timestamps às mensagens de log.

Exemplo:

cat file | tai64n | tai64nlocal

Se o valor que você está prefixando for o mesmo em todas as linhas, ative o emacs com o arquivo e:

Ctrl + <espaço>

no início do arquivo (para marcar o ponto), role para baixo até o início da última linha (Alt +> irá para o final do arquivo ... o que provavelmente envolverá a tecla Shift também, então Ctrl + a para ir ao começo dessa linha) e:

Ctrl + x r t

Qual é o comando para inserir no retângulo que você acabou de especificar (um retângulo de largura 0).

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

Ou o que quer que você prefira ... então você verá esse texto prefixado em todas as linhas dentro do retângulo de 0 na largura.

ATUALIZAÇÃO: Eu acabei de perceber que você não quer a MESMA data, então isso não vai funcionar ... embora você possa fazer isso no emacs com uma macro customizada um pouco mais complicada, mas ainda assim, esse tipo de edição de retângulo é muito bom saber sobre ...


fazendo com date e tr e xargs no OSX:

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

Se você quiser milissegundos:

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

mas note que no OSX, date não lhe dá a opção% N, então você precisará instalar o gdate ( brew install coreutils ) e então finalmente chegará a isto:

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

annotate , disponível através desse link ou como annotate-output no pacote 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

Isenção de responsabilidade : a solução que estou propondo não é um utilitário interno do Unix.

Eu enfrentei um problema semelhante há alguns dias. Eu não gostei da sintaxe e das limitações das soluções acima, então eu rapidamente montei um programa em Go para fazer o trabalho para mim.

Você pode verificar a ferramenta aqui: preftime

Existem executáveis ​​pré-construídos para Linux, MacOS e Windows na seção Releases do projeto GitHub.

A ferramenta lida com linhas de saída incompletas e tem (do meu ponto de vista) uma sintaxe mais compacta.

<command> | preftime

Não é o ideal, mas eu gostaria de compartilhar, caso isso ajude alguém.


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




awk