如何在从 STDIN 读取的行前面加上纪元时间戳?

如何在从 STDIN 读取的行前面加上纪元时间戳?

我想前置纪元时间到一行参数。我想要的输出是:

$ echo foo bar baz | some_bash_awk_sed_date_program_or_something_else
1491146539 foo bar baz

我得到的实际输出如下所示:

$ echo foo bar baz | awk -f time_stamper.awk
1491146539
0 foo bar baz

我的time_stamper.awk

BEGIN { 
OFS=" "
printf "%s ", system("date +'%s'")
}
{ print }

我认为领先0来自于返回值date +'%s'。我期望设置OFS=" "至少会返回将1491146539 0 foo bar baz换行符更改为空格。

关于我当前尝试的一些问题:

  • 我对OFS 内置变量
  • 为什么印刷0在前面foo bar baz

更重要的是,我不确定这是否awk是适合这项工作的工具。也许我应该使用seddate其他一些实用程序。

  • 如何打印所需的输出?

注意:这个问题更加具体,因此与这个问题。另外,回答需要安装更多实用程序这似乎是 Unix 工具集的一个有趣的补充;然而,我宁愿坚持使用更传统的 Unix 实用程序来执行我的任务。

答案1

system()函数awk运行命令并返回其状态。你得到了0,因为命令成功了。的输出date +'%s'是单独打印的。

要获取外部命令的输出,您可以使用获取线()

$ echo foo bar baz | awk '{"date +%s" | getline d; printf "%s %s\n", d, $0}'
1491147643 foo bar baz

与 无关OFS,因为默认情况下它是一个空格。


使用gawkmawk,您还可以执行以下操作:

echo foo bar baz | gawk '{printf "%s %s\n", systime(), $0}'

返回systime()自纪元以来的秒数,不包括闰秒


IOW,你可以单独完成date

date +'%s foo bar baz'

答案2

重击
在这里,我们使用while循环从 stdin 获取参数,并且不执行任何拆分,因为我们IFS=使用read.这使得整行以及伴随的空白得以保留。最后,我们现在echo可以timestamp通过变量获得参数$l。需要记住的一点是,echo为了代码的可预测行为,所有参数都需要被引用。

echo 'foo     bar baz' | while IFS= read -r l; do echo "$(date +'%s')" "$l"; done

珀尔

-n 选项指示Perl逐行读取文件+除非特别要求否则不要打印。读入的每一行都存储在$_相当于$0of中awktime()是一个Perl builtin给我们epoch时间的函数。然后我们将纪元时间和当前行放入一个anonymous数组引用中[ ..., ... ],并通过它返回该数组的内容dereferencing,表达式周围的@{ ... }双引号确保列表元素以空格分隔。然后我们打印它们。"..."@{...}

echo ... |  perl -ne 'print "@{[+time,$_]}"'

IFS= read -r l <<<"$(echo 'foo    bar baz')"
printf '%d %s\n' "$(date +'%s')" "$l"

答案3

这也可以使用 sed as 来完成

代码:

 echo 1 2 3 | sed 's/^/'`date +"%s"`' /'

结果:

1491148928 1 2 3

相关内容