Bash中如何使用gawk为控制台输出的时间戳添加毫秒精度
gawk输出时间戳增加毫秒字段的实现方式
原命令使用的strftime()函数仅支持秒级精度的时间格式化,无法直接输出毫秒字段,需要额外获取亚秒级时间值拼接,以下是两种可直接使用的方案:
- 高性能方案(推荐,适配gawk 4.0及以上版本,目前绝大多数主流Linux发行版预装的gawk都满足版本要求)
加载gawk内置的time扩展库,通过gettimeofday()获取微秒级时间戳,拆分秒级部分做常规格式化,小数部分转换为3位毫秒值拼接即可:
格式化毫秒时用command | gawk '@load "time"; { now = gettimeofday() printf "[%s.%03d] %s\n", strftime("%Y-%m-%d %H:%M:%S", int(now)), int((now - int(now))*1000), $0 }'%03d是为了自动补前导零,固定输出3位数值,避免出现[2024-05-20 12:30:05.2]这类不规范的时间格式。 - 兼容方案(适配低版本gawk,适合低频率输出场景)
每行处理时调用GNU date命令直接生成带毫秒的格式化时间,注意每次调用后必须关闭命令管道,否则会出现时间不刷新、残留僵尸进程的问题:
其中date参数的command | gawk '{ cmd = "date +\"%Y-%m-%d %H:%M:%S.%3N\"" cmd | getline ts close(cmd) printf "[%s] %s\n", ts, $0 }'%3N表示取纳秒值的前3位,对应毫秒精度。
注意:不少程序在输出到管道而非终端时,会默认开启全缓冲模式,导致日志攒够一定量才一次性输出、时间戳和实际输出时间不匹配。遇到这种情况可以在原命令前加
stdbuf -oL强制开启行缓冲,示例:stdbuf -oL your_command | gawk '@load "time"; { now = gettimeofday(); printf "[%s.%03d] %s\n", strftime("%Y-%m-%d %H:%M:%S", int(now)), int((now - int(now))*1000), $0 }'
内容的提问来源于stack exchange,提问作者Rohit Dwivedi
相关产品推荐
相关产品推荐

