将bash命令输出中的substring替换为另一个命令的返回值(例如,将时间戳转换为日期)

时间:2017-01-19 14:07:51

标签: bash sed freebsd

我有一个输出Unix时间戳后跟一些文本的命令:

> mycommand
1484169138 happened XYZ
1484169139 happened XZY
...

我想将时间戳转换为人类可读的字符串,但似乎无法弄清楚如何。

我尝试了各种工具(例如sedawk)。以下answer on stackoverflow似乎非常接近;但我在FreeBSD上似乎没有GNU扩展来使用e

$ mycommand |sed -E 's#([0-9]{10})#date -r \1#e'
sed: 1: "s#([0-9]{10})#date -r \1#e": bad flag in substitute command: 'e'

2 个答案:

答案 0 :(得分:1)

你可以在POSIX shell的while循环中使用date命令重新格式化日期(我应该指出它可能不是你在FreeBSD中的默认shell)。

$ while read d t; do printf "[%s] %s\n" "$(date -r "$d" '+%F %T')" "$t"; done < x.txt
[2017-01-11 16:12:18] happened XYZ
[2017-01-11 16:12:19] happened XZY

while循环也可以是管道的结尾:

$ mycommand | while read d t; do ...; done

答案 1 :(得分:1)

BSD sed不支持GNU - sed特定的/e选项,该选项允许使用shell命令在s函数调用中提供替换字符串,正如你所发现的那样。

但是,awk可以提供类似的功能:

$ awk '{ ("date -r " $1) | getline $1 } 1' <<'EOF'
1484169138 happened XYZ
1484169139 happened XZY
EOF
Wed Jan 11 16:12:18 EST 2017 happened XYZ
Wed Jan 11 16:12:19 EST 2017 happened XZY
  • ("date -r " $1)从第1个字段构造一个shell命令,其中包含以秒为单位的Unix纪元时间,例如date -r 1484169138,它位于东部时区的具有en-US区域设置的系统上收益率Wed Jan 11 16:12:18 EST 2017(请注意 GNU date的{​​{1}}选项完全具有不同的语义。

  • -r执行shell命令(通过... | getline $1)并在变量sh -c中捕获命令的stdout输出;即,用命令的输出替换第一个字段。

  • $1是简单打印(修改后)记录的常用简写。