是否有一个Unix工具预加时间戳到标准input?

我最终在Python中为此写了一个快速的小脚本,但是我想知道是否有一个实用程序可以给文本添加文本,在文本中添加一些文本 – 在我的具体情况下是时间戳。 理想情况下,使用会是这样的:

cat somefile.txt | prepend-timestamp 

(在你回答sed之前,我试过这个:

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

但是,执行sed时只会计算一次date命令,所以相同的时间戳被错误地添加到每行。

可以尝试使用awk

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

您可能需要确保<command>产生行缓冲输出,也就是每行之后刷新其输出stream; awk添加的时间戳将会是行尾出现在inputpipe道上的时间。

如果awk显示错误,请尝试使用gawk

来自moreutils的 ts会为您提供的每一行input添加一个时间戳。 你也可以使用strftime格式化它。

 $ 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 $ 

要安装它:

 sudo apt-get install moreutils 

注释 ,可通过该链接获得,或作为Debian devscripts包中的annotate-output

 $ 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 

提供最简单的答案是可能的:

 unbuffer $COMMAND | ts 

在Ubuntu上,他们来自expect-dev和moreutils软件包。

 sudo apt-get install expect-dev moreutils 

这个怎么样?

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

从您希望获得实时时间戳的angular度来看,也许您想要在日志文件上进行实时更新? 也许

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

只是要把它扔出去:在守护 进程中有一对称为tai64n和tai64nlocal的实用程序,用于预先设置时间戳以logging消息。

例:

 cat file | tai64n | tai64nlocal 

基隆的答案是迄今为止最好的答案。 如果由于第一个程序将其缓冲出来而遇到问题,则可以使用unbuffer程序:

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

它在大多数Linux系统上默认安装。 如果你需要自己构build它,它是期望包的一部分

http://expect.nist.gov

使用read(1)命令从标准input一次读取一行,然后使用date(1)输出以您select的格式添加date的行。

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

我不是一个Unix的人,但我认为你可以使用

 gawk '{print strftime("%d/%m/%y",systime()) $0 }' < somefile.txt 
 #! /bin/sh unbuffer "$@" | perl -e ' use Time::HiRes (gettimeofday); while(<>) { ($s,$ms) = gettimeofday(); print $s . "." . $ms . " " . $_; }' 

这里是我的awk解决scheme(来自安装在C:\ bin目录中的MKS工具的Windows / XP系统)。 它被devise成将当前的date和时间以mm / dd hh:mm的forms添加到从系统读取每行的时间戳的每一行的开始处。 当然,您可以使用BEGIN模式获取一次时间戳,并将该时间戳添加到每条logging(全部相同)。 我这样做是为了在生成日志消息的时候用时间戳标记一个正在生成的stdout日志文件。

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

其中“pattern”是在input行中匹配的string或正则expression式(不带引号),如果希望匹配所有input行,则是可选的。

这应该也适用于Linux / UNIX系统,只是摆脱C \:\\ bin \\离开线路

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

这当然假设命令“date”可以让你在没有特定path信息(也就是你的环境PATHvariables被正确configuration)的情况下进入标准的Linux / UNIXdate显示/设置命令。

caerwyn的答案可以作为一个子程序运行,这将阻止每行的新进程:

 timestamp(){ while read line do echo `date` $line done } echo testing 123 |timestamp 
 $ cat somefile.txt | sed "s/^/`date`/" 

你可以这样做(用gnu / sed ):

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

例:

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

当然,您也可以使用程序date的其他选项。 只需用你所需要的date +%T代替。

在OSX上用datetrxargs来做:

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

如果你想毫秒:

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

但是请注意,在OSX上,date不会给你%N选项,所以你需要安装gdate( brew install coreutils ),最后到达这个:

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

从natevw和Frank Ch混合一些上面的答案。 Eigler。

它有毫秒,比每次调用一个外部的date命令更好,perl可以在大多数服务器中find。

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

替代版本与刷新和阅读循环:

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

免责声明 :我提出的解决scheme不是Unix内置的实用程序。

我前几天遇到了类似的问题。 我不喜欢上述解决scheme的语法和限制,所以我很快就把一个程序放在Go上为我做这个工作。

你可以在这里检查工具: preftime

在GitHub项目的Releases部分有针对Linux,MacOS和Windows的预构build可执行文件。

该工具处理不完整的输出行,并且(从我的angular度来看)一个更紧凑的语法。

<command> | preftime

这不是理想的,但我虽然会分享它,以防止他人帮助。

如果您预先设置的值在每行上都相同,则使用该文件启动emacs,然后:

Ctrl + <空格>

在文件的开始处(标记该点),然后向下滚动到最后一行的开头(Alt +>将进入文件的结尾,这可能也会涉及到Shift键,然后Ctrl + a去该行的开头)和:

Ctrl + x r t

在刚刚指定的矩形中插入的命令(0宽度的矩形)。

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

或者你想要预先考虑的东西…然后你会看到在0宽度的矩形内的每一行都预设了文本。

更新:我只是意识到你不想要相同的date,所以这将无法正常工作…虽然你可以用一个稍微复杂的自定义macros在emacs中做到这一点,但这种矩形编辑仍然是很高兴知道…