在命令的每一行输出前添加时间戳

在命令的每一行输出前添加时间戳

我希望在命令的每一行输出前面添加一个时间戳。例如:

foo
bar
baz

会成为

[2011-12-13 12:20:38] foo
[2011-12-13 12:21:32] bar
[2011-12-13 12:22:20] baz

...其中前缀时间是打印该行的时间。我怎样才能实现这个目标?

答案1

更多实用程序包括ts它做得很好:

command | ts '[%Y-%m-%d %H:%M:%S]'

它也消除了对循环的需要,每行输出都会有一个时间戳。

$ echo -e "foo\nbar\nbaz" | ts '[%Y-%m-%d %H:%M:%S]'
[2011-12-13 22:07:03] foo
[2011-12-13 22:07:03] bar
[2011-12-13 22:07:03] baz

您想知道您重新启动的服务器何时恢复?只要运行ping | ts,问题就解决了:D。

笔记:用于[%Y-%m-%d %H:%M:%.S]微秒精度。

答案2

首先,如果您期望这些时间戳实际上代表一个事件,请记住,由于许多程序执行行缓冲(有些程序比其他程序更积极),因此重要的是要将其视为接近原始行的时间。被打印而不是发生的操作的时间戳。

您可能还想检查您的命令是否还没有专门用于执行此操作的内置功能。例如,ping -D存在于某些ping版本中,并在每行之前打印自 Unix 纪元以来的时间。但是,如果您的命令不包含自己的方法,则可以使用一些方法和工具,其中包括:

POSIX外壳

请记住,由于许多 shell 在内部将其字符串存储为 cstring,因此如果输入包含空字符 ( \0),则可能会导致该行过早结束。

command | while IFS= read -r line; do printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line"; done

GNU awk

command | gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }'

珀尔

command | perl -pe 'use POSIX strftime; print strftime "[%Y-%m-%d %H:%M:%S] ", localtime'

Python

command | python -c 'import sys,time;sys.stdout.write("".join(( " ".join((time.strftime("[%Y-%m-%d %H:%M:%S]", time.localtime()), line)) for line in sys.stdin )))'

红宝石

command | ruby -pe 'print Time.now.strftime("[%Y-%m-%d %H:%M:%S] ")'

答案3

对于逐行增量测量,请尝试晷针

它是一个命令行实用程序,有点像 moreutils 的 ts,用于将时间戳信息添加到另一个命令的标准输出中。对于长时间运行的流程非常有用,在这些流程中您想要花费这么长时间的历史记录。

将任何内容通过管道传输到 gnomon 都会在每一行前面添加一个时间戳,指示该行是缓冲区中最后一行的时间,即下一行出现需要多长时间。默认情况下,gnomon 将显示每行之间经过的秒数,但这是可配置的。

指针演示

答案4

2024年更新

下面描述的伟大ets程序自 2020 年以来尚未更新,因此截至 2024 年 4 月,您可以考虑从以下位置获取其更新的分支:https://github.com/gdubicki/ets并发布了新版本。

原答案

我刚刚为解决这个问题而写的东西的无耻插件:ets,用 Go 编写。

演示

您可以在项目页面上找到很多使用示例。

与现有答案和类似产品的显着区别在于,它ets旨在在 pty(伪 tty)中为您运行命令 - 也就是说,模拟您的命令在 tty 中本机运行。与将命令输出通过管道传输到 eg 相比ts,这使得时间戳基本上是透明的,并解决了一系列管道问题:

  • 有些程序在写入管道时会积极缓冲,因此您看不到任何输出,然后看到一大堆输出(是的,您可以对它们进行 stdbuf,您甚至可以将 stdbuf 和 ts 包装在别名/函数中,但这不是更好吗?如果开箱即用);
  • 有些程序在写入管道时会禁用颜色和/或交互性;
  • 除非你打开pipefail,否则退出状态消失; ETC。

命令可以直接执行,这意味着您可以简单地添加ets到现有命令行之前,或者它们可以是 shell 命令(如上面的 gif 所示)。当然,如果你想通过管道输出,ets也可以这样做。

ets支持与 moreutils 相同的时间戳模式ts:绝对时间模式、经过时间模式和增量时间模式。它使用更合理的默认值(例如,单调时钟始终用于经过/增量时间戳),并且对自定义时区有额外的支持。有详细的对比这里

再次,https://github.com/zmwangx/ets。试一试,报告错误等。

相关内容