Answers:
可以尝试使用awk
:
<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush(); }'
您可能需要确保<command>
产生行缓冲输出,即在每行之后刷新其输出流。时间戳awk
添加将是该行的末尾出现在其输入管道上的时间。
如果awk显示错误,请尝试gawk
。
gawk
并使用它而不是awk
。如果您有MacPorts:sudo port install gawk
awk
的strftime()
精度不是毫秒。但是,您可以使用date
命令。基本上,您只需将纳秒修剪为三个字符。它看起来是这样的:COMMAND | while read -r line; do echo "$(date '+%Y-%m-%d %T.%3N') $line"; done
。请注意,您可以将%H:%M:%S缩写为%T。如果您仍然awk
出于某些原因想要使用,可以执行以下操作:COMMAND | awk '{ "date +%Y-%m-%d\\ %T.%3N" | getline timestamp; print timestamp, $0; fflush(); }'
ts
from moreutils中的时间戳将在您输入的每一行之前加上时间戳。您也可以使用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
bad command 2>&1 | ts
结果Jan 29 19:58:31 -bash: bad: command not found
2014 Mar 21 18:07:28
。我如何得到它?
brew install moreutils
。要输出UTC,可以在本地设置TZ,例如ls -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'
注解,可以通过该链接获得,也可以annotate-output
在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
将给出的答案简化为最简单的答案:
unbuffer $COMMAND | ts
在Ubuntu上,它们来自Expect-dev和moreutils软件包。
sudo apt-get install expect-dev moreutils
expect
,不是expect-dev
,但是后者引入了前者,因此可行。(Ubuntu 14.10,我想知道二进制文件是否在某个时候被转移到了另一个软件包。)
expect-dev
unbuffer $COMMAND | ts -s %.s
(-s
如果经过的时间和%.s
以秒为单位的时间以分数为单位)
这个怎么样?
cat somefile.txt | perl -pne 'print scalar(localtime()), " ";'
从您希望获得实时时间戳的角度来看,也许您想对日志文件或其他内容进行实时更新?也许
tail -f /path/to/log | perl -pne 'print scalar(localtime()), " ";' > /path/to/log-with-timestamps
tail -f /path/to/log | perl -pne 'use POSIX qw(strftime); print strftime "%Y-%m-%dT%H:%M:%SZ ", gmtime();'
获得过ISO8601 / RFC3339样式的日期,而不是简单版本产生的wacko。
ls | perl -pne 'print localtime." "'
。标量转换是由于字符串串联而发生的。
-p
和-n
选项?-n
如果指定,似乎是多余的-p
。
Kieron的答案是迄今为止最好的答案。如果由于第一个程序正在缓冲它而遇到问题,则可以使用unbuffer程序:
unbuffer <command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'
大多数Linux系统默认安装了它。如果您需要自己构建它,则它是Expect包的一部分
#! /bin/sh
unbuffer "$@" | perl -e '
use Time::HiRes (gettimeofday);
while(<>) {
($s,$ms) = gettimeofday();
print $s . "." . $ms . " " . $_;
}'
这是我的awk解决方案(来自Windows / XP系统,在C:\ bin目录中安装了MKS工具)。它的设计目的是将当前日期和时间以mm / dd hh:mm的形式添加到在读取每一行时已从系统中获取了该时间戳记的每一行的开头。当然,您可以使用BEGIN模式获取时间戳一次,并将该时间戳添加到每条记录中(全部相同)。我这样做是为了将生成的日志文件标记为带有日志消息生成时的时间戳的stdout。
/"pattern"/ "C\:\\\\bin\\\\date '+%m/%d %R'" | getline timestamp;
print timestamp, $0;
其中“模式”是要在输入行中匹配的字符串或正则表达式(不带引号),如果希望匹配所有输入行,则为可选。
这也应该在Linux / UNIX系统上工作,只需摆脱C \:\\ bin \\
"date '+%m/%d %R'" | getline timestamp;
当然,这假设命令“ date”将您带到标准Linux / UNIX date display / set命令,而没有特定的路径信息(也就是说,您的环境PATH变量已正确配置)。
混合以上natevw和Frank Ch。艾格勒
它具有毫秒数,比date
每次调用外部命令都要好,并且在大多数服务器中都可以找到perl。
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);
}'
printf "%s+%06d %s", (strftime "%Y-%m-%dT%H:%M:%S", gmtime($s)), $ms, $_;
caerwyn的答案可以作为子例程运行,这将阻止每行新的进程:
timestamp(){
while read line
do
echo `date` $line
done
}
echo testing 123 |timestamp
date
每行产生?
timestamp() { while read line; do echo "$(date) $line"; done; }; export -f timestamp
在您获取的脚本中。
date
每行生成命令,请尝试使用%(datespec)T格式的printf
内置bash 。因此可能看起来像。Shell内置插件不会生成。Datespec格式类似于即格式。这需要bash,不能确定,因为它支持该说明符的版本。timestamp() { while IFS= read -r line; do printf "%(%F %T)T %s\n" -1 "$line"; done; }
strftime(3)
date
printf
在OSX上使用date
and tr
和这样做xargs
:
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 \"{}\"'"
如果您要附加的值在每一行都相同,请使用该文件启动emacs,然后:
Ctrl + <space>
在文件的开头(以标记该点),然后向下滚动到最后一行的开头(Alt +>将转到文件的结尾...这可能也需要使用Shift键,然后按Ctrl + a转到该行的开头),然后:
Ctrl + x r t
这是要在您刚刚指定的矩形(宽度为0的矩形)上插入的命令。
2008-8-21 6:45 PM <enter>
或任何您想添加的内容...然后,您将看到该文本添加到0宽度矩形内的每一行。
更新:我只是意识到您不希望使用相同的日期,因此这将无法工作...尽管您可以使用稍微复杂一些的自定义宏在emacs中执行此操作,但是仍然可以进行这种矩形编辑很高兴知道...
cat somefile.txt
有点“误导”?我希望它可以“一次”发生,并且只有一个时间戳。这不是更好的测试程序(echo a; sleep 1; echo b; sleep 3; echo c; sleep 2)
吗?