【发布时间】:2015-07-03 02:19:48
【问题描述】:
我有每行包含多个部分的 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
为什么第一个命令没有按预期运行?
我现在最好的猜测是,首先执行子shell而不用\1替换,然后sed实际使用结果输出。
我如何实现我想要做的事情?
附:我正在使用 CentOS 6.6
【问题讨论】:
-
请注意,您正在打开一个子shell 来执行命令,因此该值可能不会“到达”那里。此外,要在
sed中执行命令,您需要/e。 -
如果您将
\\1替换为-2156284800,您将看到它可以工作,这表明\\1与之前的字符串不匹配,原因由@fedorqui 描述。 Fedorqui,你不需要/e,因为这对我有用? -
我尝试了 gnu sed 的 'e' 选项。 echo "bla foo bla foo" | sed -e "s@(foo)@echo XX\1XX@e" 期望输出:bla XXfooXX bla XXfooXX 实际输出:sh: bla: command not found
-
使用适当的 JSON 解析器用一种语言编写脚本会容易得多。