如何在sed中更改日期格式?

时间:2015-12-03 16:23:04

标签: bash date sed

假设我想通过date命令将时间戳中的日期转换为另一种格式。在控制台中我会说date -d@<timestamp>但我碰巧想对文本文件中的许多字段执行此操作。

使用e执行sedsed (GNU sed) 4.2.2,实际上)我说:

$ echo 1449158360 | sed -r 's#.*([0-9]{10}).*#date -d@\1 "+%Y";#e'
2015

很有效!

现在我创建了一个虚拟文件myfile

my timestamp is 1449158360 but also I wonder what date was 1359199960.

我希望将其替换为相同但具有时间戳的相对年份:

my timestamp is 2015 but also I wonder what date was 2013.

但是,如果我尝试运行与上面相同的命令,则会失败:

$ sed -r 's#([0-9]{10})#date -d@"\1" "+%Y";#e' myfile
sh: my: command not found
sh: but: command not found

因为sed将第一个单词解释为要执行的内容。

显然,如果我只是获取这些数据,那么它就可以了:

$ sed -r 's#.*([0-9]{10}).*#date -d@"\1" "+%Y";#ge' myfile
2015

所以我想知道:我应该怎么做才能在date中针对捕获的群组调用sed,并用它替换文字,考虑到它被其他文本包围,必须保持不变?

2 个答案:

答案 0 :(得分:4)

e切换sed替换将sh -c应用于不匹配的文本,以及此命令中显而易见:

echo 'a 1449158360' | sed -r 's#([0-9]{10})#date -d@\1 "+%Y";#e'
sh: a: command not found 

即使我们仅匹配1449158360,但sh -c正在a 1449158360上运行。

由于sed中缺少非贪婪和前瞻性正则表达式,此解决方法正则表达式可能看起来很疯狂,但这就是如何在文件中为多个匹配输入运行它,如问题所示:

sed -r 's#(([^0-9][0-9]{0,9})*)(\b[0-9]{10}\b)(([0-9]{0,9}[^0-9])*)#printf "%s%s%s" "\1" $(date -d@\3 "+%Y") "\4";#ge' file

基本上我们在此正则表达式中匹配<before>10-digits<after>

<强>输出:

my timestamp is 2015 but also I wonder what date was 2013.

为了澄清我使用的正则表达式,我创建了this demo

这绝不是e模式问题的通用解决方案,将其视为基于正则表达式的解决方法。

答案 1 :(得分:0)

正如你所说,使用e标志myfile将所有句子作为执行的句子。

转变可能就是这样。

echo "my timestamp is 1449158360 but also I wonder what date was 1359199960." 更改为:

sed -r 's#([0-9]{10})#\`date -d@\1 "+%Y"\`#ge' myfile

然后:

sed -r 's/ $/,/'

希望有帮助