0

我有一个问题,如何使用 sed 将日期从“2012 年 6 月 14 日下午 5:00”转换为“2012-06-14”?因此也省略了“下午 5:00”。我正在尝试类似的东西,s/(...)(\d\d)(\d\d\d\d)/$2.$1.$3/但无法做到。谢谢!

4

3 回答 3

2

你真的不需要 sed 来做 - 你需要日期:

$ date --date='Jun 14 2012 5:00PM' '+%Y-%m-%d'
2012-06-14

在此命令中,我要求 date 将日期转换'Jun 14 2012 5:00PM'为由四位数年份 ( %Y) 后跟连字符和两位数月份 ( %m) 后跟另一个连字符和两位数日期 ( %d) 组成的格式。

现在,关于您的 sed 命令的一些说明:

Sed 使用特定的、有些受限的正则表达式语法。区别之一是括号组之前应该有反斜杠以进行有效分组。如果没有反斜杠,则括号被视为文字括号字符。我知道,这与其他语言中的正则表达式完全相反,但这就是它的工作方式。所以,而不是

s/(...)(\d\d)(\d\d\d\d)/$2.$1.$3/

你应该有

s/\(...\)\(\d\d\)\(\d\d\d\d\)/$2.$1.$3/

此外,sed 中没有\d通配符。相反,您应该使用[[:digit:]]

s/\(...\)\([[:digit:]][[:digit:]]\)\([[:digit:]][[:digit:]][[:digit:]][[:digit:]]\)/$2.$1.$3/

或者,更好的是:

s/\(...\)\([[:digit:]]\{2\}\)\([[:digit:]]\{4\}\)/$2.$1.$3/

最后但并非最不重要的一点是,对匹配组的引用不是用 标记$,而是用反斜杠标记:

    s/\(...\)\([[:digit:]]\{2\}\)\([[:digit:]]\{4\}\)/\2.\1.\3/

(哦,呃,好吧,你也可以在 GNU sed 中使用扩展的正则表达式,但是有什么好玩的呢?)

无论如何,这也与您的日期不匹配 - 我刚刚提到了语法错误,也存在一些语义错误(例如,您的日期由正则表达式中不存在的空格分隔)。尽管如此,这没有问题,因为 date 可以做得更好。

于 2012-06-18T12:30:21.860 回答
1

这可能对您有用:

echo "Jun 14 2012 5:00PM" |
sed 's/$/Jan01Feb02Mar03Apr04May05Jun06Jul07Aug08Sep09Oct10Nov11Dec12/;s/\(...\) \(..\) \(....\).*\1\(..\).*/\3-\2-\4/'
2012-14-06

使用反向引用添加查找和匹配。

于 2012-06-18T20:51:45.840 回答
0

你可以试试这样的 -

echo "Jun 21 2011 5:00PM" | 
awk '{"date \"+%Y/%m/%d\" -d \""$1" "$2" "$3" \"" | getline var; print var}'

测试:

$ echo "Jun 21 2011 5:00PM" | 
awk '{"gdate \"+%Y/%m/%d\" -d \""$1" "$2" "$3" \"" | getline var; print var}'
2011/06/21
$
于 2012-06-19T05:30:48.410 回答