我的json行每行包含多个部分,如下所示:
"SomeDate":"Date(-2156284800000)",
我想将所有行中的每一个事件转换为更易于阅读的内容:
"SomeDate":"1901-09-03 00:19:32",
我尝试使用sed将匹配的块(在本例中为时间戳)放入date命令的参数列表中。这失败了。
$ echo '"SomeDate":"Date(-2156284800000)",' | \
sed "s/Date(\([0-9\-]*\)[0-9][0-9][0-9])/$(date -d@\\1 \"+%F %T\")/g"
date: invalid date `@\\1'
"SomeDate":"",
为了尝试调试这一切,我在日期中添加了一个'echo'来验证它应该运行的命令
$ echo '"SomeDate":"Date(-2156284800000)",' | \
sed "s/Date(\([0-9\-]*\)[0-9][0-9][0-9])/$(echo date -d@\\1 \"+%F %T\")/g"
"SomeDate":"date -d@-2156284800 "+%F %T"",
$ date -d@-2156284800 "+%F %T"
1901-09-03-00:19:32
为什么第一个命令不按预期运行?
我现在最好的猜测是,在没有\ 1替换的情况下首先执行子shell,然后生成的输出实际上由sed使用。
我如何实现我的目标?
P.S。我正在使用CentOS 6.6
答案 0 :(得分:0)
如何使用awk:
echo '"SomeDate":"Date(-2156284800000)",' | awk '{ print gensub(/Date\(([0-9\-]+)\)/, ("date -d@\\1 \"+%F %T\"" |& getline t) ? t : "\\1", "g"); }'
免责声明:可能有更好的方法,但简单地说:
gensub
与gsub
类似,但可让您访问匹配的群组使用以下方法捕获日期(XXX)位
/Date\(([0-9\-]+)\)/
(获取匹配组中的实际纪元\1
)
第二个参数是:
("date -d@\\1 \"+%F %T\"" |& getline t) ? t : "\\1"
形成date命令,运行它(带getline
)并将结果赋给变量t
。 getline
,成功地返回1
,因此我们使用三元(?:
)语句检查它并返回该命令的第一行输出。
最后,我们告诉gensub
是全球性的。
答案 1 :(得分:0)
我现在使用的解决方法是通过perl:
$ echo fee 4321432431 fie 1429882795 fum | \
perl -MPOSIX -pe 's/(\d+)/strftime "%F", localtime $1/eg'
fee 2106-12-10 fie 2015-04-24 fum