Acabei escrevendo um pequeno script rápido para isso em Python, mas fiquei imaginando se havia um utilitário no qual você pudesse alimentar o texto que precederia cada linha com algum texto - no meu caso específico, um carimbo de data / hora. Idealmente, o uso seria algo como:
cat somefile.txt | prepend-timestamp
(Antes de responder sed, tentei o seguinte:
cat somefile.txt | sed "s/^/`date`/"
Mas isso avalia apenas o comando date uma vez quando o sed é executado; portanto, o mesmo timestamp incorretamente é anexado incorretamente a cada linha.)
cat somefile.txt
um pouco "enganoso"? Eu esperava que isso acontecesse "de uma só vez" e tivesse um único registro de data e hora. Este não seria um programa de teste melhor(echo a; sleep 1; echo b; sleep 3; echo c; sleep 2)
:?Respostas:
Pode tentar usar
awk
:Você pode precisar se certificar de que
<command>
produz saída em buffer de linha, ou seja, libera seu fluxo de saída após cada linha; o registro de data e horaawk
adiciona será o horário em que o final da linha apareceu em seu canal de entrada.Se o awk mostrar erros, tente
gawk
.fonte
gawk
e usar isso em vez deawk
. Se você tem MacPorts:sudo port install gawk
awk
'sstrftime()
não tem precisão de milissegundos. No entanto, você pode usar odate
comando Basicamente, você apenas apara nanossegundos para três caracteres. Ele será parecido com este:COMMAND | while read -r line; do echo "$(date '+%Y-%m-%d %T.%3N') $line"; done
. Observe que você pode abreviar% H:% M:% S com% T. Se você ainda deseja usá-loawk
por algum motivo, pode fazer o seguinte:COMMAND | awk '{ "date +%Y-%m-%d\\ %T.%3N" | getline timestamp; print timestamp, $0; fflush(); }'
ts
de moreutils irá anteceder um timestamp para cada linha de entrada que dá-lo. Você pode formatá-lo usando strftime também.Para instalá-lo:
fonte
bad command 2>&1 | ts
resulta emJan 29 19:58:31 -bash: bad: command not found
2014 Mar 21 18:07:28
. Como faço para obtê-lo?strftime
string de formato como argumento :,[.. command ..] | ts '%Y %b %d %T'
por exemplo.brew install moreutils
,. Parals -l |TZ=UTC ts '%Y-%m-%dT%H:%M:%SZ'
ruby -e "puts 1; STDOUT.flush; sleep 1; puts 2; STDOUT.flush; sleep 2; puts 3" | ts '%F %T'
anote , disponível através desse link ou como
annotate-output
nodevscripts
pacote Debian .fonte
Destilando as respostas dadas para a mais simples possível:
No Ubuntu, eles vêm dos pacotes expect-dev e moreutils.
fonte
expect
, nãoexpect-dev
, mas o último puxa na antiga assim isso funciona. (Ubuntu 14.10, eu me pergunto se o binário foi transferido para um pacote diferente em algum ponto.)expect-dev
unbuffer $COMMAND | ts -s %.s
(-s
se por tempo decorrido e%.s
para o tempo em segundos com parte fracionária)Que tal agora?
A julgar pelo seu desejo de obter registros de data e hora ao vivo, talvez você queira atualizar ao vivo em um arquivo de log ou algo assim? Talvez
fonte
tail -f /path/to/log | perl -pne 'use POSIX qw(strftime); print strftime "%Y-%m-%dT%H:%M:%SZ ", gmtime();'
obter uma data no estilo ISO8601 / RFC3339, em vez da wacko que a versão mais simples gera.BEGIN { $|++; }
antes da instrução de impressão para que o Perl libere sua saída com cada linha.ls | perl -pne 'print localtime." "'
. A conversão escalar ocorre devido à concatenação de cadeias.-p
e-n
opções? Parece que-n
é redundante se você especificou-p
.Só vamos divulgar isso: há um par de utilitários no daemontools, chamados tai64n e tai64nlocal, que são feitos para anexar timestamps para registrar mensagens.
Exemplo:
fonte
A resposta de Kieron é a melhor até agora. Se você tiver problemas porque o primeiro programa está armazenando o buffer, você pode usar o programa unbuffer:
É instalado por padrão na maioria dos sistemas Linux. Se você precisar construí-lo, isso faz parte do pacote expect
http://expect.nist.gov
fonte
Use o comando read (1) para ler uma linha de cada vez da entrada padrão e, em seguida, imprima a linha anexada com a data no formato de sua escolha usando a data (1).
fonte
Eu não sou um cara Unix, mas acho que você pode usar
fonte
fonte
Aqui está minha solução awk (de um sistema Windows / XP com o MKS Tools instalado no diretório C: \ bin). Ele foi projetado para adicionar a data e a hora atuais no formato mm / dd hh: mm ao início de cada linha, tendo buscado o registro de data e hora do sistema à medida que cada linha é lida. Obviamente, você pode usar o padrão BEGIN para buscar o carimbo de data / hora uma vez e adicioná-lo a cada registro (todos iguais). Fiz isso para marcar um arquivo de log que estava sendo gerado para stdout com o carimbo de data e hora 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) a serem correspondidas na linha de entrada e é opcional se você deseja corresponder a todas as linhas de entrada.
Isso deve funcionar em sistemas Linux / UNIX também, basta se livrar do C \: \\ bin \\ saindo da linha
Obviamente, isso pressupõe que o comando "date" leva você ao comando padrão de exibição / configuração da data do Linux / UNIX sem informações específicas do caminho (ou seja, a variável PATH do ambiente está configurada corretamente).
fonte
Misturando algumas respostas acima de natevw e Frank Ch. Eigler.
Possui milissegundos, executa melhor do que chamar um
date
comando externo toda vez e o perl pode ser encontrado na maioria dos servidores.Versão alternativa com flush e leia em um loop:
fonte
printf "%s+%06d %s", (strftime "%Y-%m-%dT%H:%M:%S", gmtime($s)), $ms, $_;
você pode fazer isso (com gnu / sed ):
exemplo:
é claro, você pode usar outras opções da data do programa . apenas substitua
date +%T
pelo que você precisa.fonte
A resposta de caerwyn pode ser executada como uma sub-rotina, o que impediria os novos processos por linha:
fonte
date
seja gerado em todas as linhas?timestamp() { while read line; do echo "$(date) $line"; done; }; export -f timestamp
em um script que você forneça.date
para todas as linhas, tente usar o bashprintf
embutido com o formato T% (dataspec) . Então pode parecertimestamp() { while IFS= read -r line; do printf "%(%F %T)T %s\n" -1 "$line"; done; }
. Os componentes da Shell não aparecerão. Formato Datespec é comostrftime(3)
iedate
formatos. Isso requer bash, não sei desde que versão ele suporta esseprintf
especificador.aviso Legal : a solução que estou propondo não é um utilitário interno do Unix.
Eu enfrentei um problema semelhante há alguns dias. Não gostei da sintaxe e das limitações das soluções acima, então montei rapidamente um programa no Go para fazer o trabalho por mim.
Você pode verificar a ferramenta aqui: pré - horário
Existem executáveis pré-criados para Linux, MacOS e Windows na seção Versões do projeto GitHub.
A ferramenta lida com linhas de saída incompletas e possui (do meu ponto de vista) uma sintaxe mais compacta.
<command> | preftime
Não é o ideal, mas eu gostaria de compartilhá-lo, caso isso ajude alguém.
fonte
fazê-lo com
date
etr
exargs
no OSX:se você quiser milissegundos:
mas observe que no OSX, date não oferece a opção% N, então você precisará instalar o gdate (
brew install coreutils
) e finalmente chegar a isso:fonte
Se o valor que você está anexando for o mesmo em todas as linhas, inicie o emacs com o arquivo e:
Ctrl + <space>
no início do arquivo (para marcar esse ponto), role para baixo até o início da última linha (Alt +> irá para o final do arquivo ... o que provavelmente envolverá também a tecla Shift e, em seguida, Ctrl + a para ir para o início dessa linha) e:
Ctrl + x r t
Qual é o comando para inserir no retângulo que você acabou de especificar (um retângulo de 0 de largura).
21/08/2008 18:45 <enter>
Ou o que você quiser anexar ... então você verá esse texto anexado a todas as linhas dentro do retângulo com 0 largura.
ATUALIZAÇÃO: Acabei de perceber que você não quer a mesma data, então isso não funcionará ... embora você possa fazer isso no emacs com uma macro personalizada um pouco mais complicada, mas ainda assim, esse tipo de edição de retângulo é muito bom saber sobre ...
fonte