是的,在有人跳起来并用干草叉攻击我之前,这是一个重复的问题,但是其他问题对我来说不起作用,所以我现在自己问这个问题。
我有一个 CSV 文件,其中每个条目的某处都有日期。转换的额外困难在于,有时日期的天数只有个位数。示例条目:
abc,0,2,-2,3-16-1994
xyz,1,2,3,10-09-1994
我想要一些东西,最好是 sed,将这些数据条目转换为如下所示:
abc,0,2,-2,1994-03-16
xyz,1,2,3,1994-09-10
我试过了:
sed 's|(..)-(..)-(....)|\3-\2-\1|'
但这会产生错误,并且它实际上并没有涵盖个位数的日期问题。
我也尝试过:
awk -F - '{print $3$2$1}'
这实际上有一点预期的效果,但事实并非如此。awk 命令会转换它,但只转换月份和年份,并且不会将日期放回到原来的位置,而是将月份和年份放在行的开头,而将日期部分保留在原来的位置。
任何帮助都是极好的!
提前致谢。
编辑
评论中有人正确地指出我的例子有误。日期应该是:
abc,0,2,-2,16-03-1994
xyz,1,2,3,2-05-1994
期望结果是:
abc,0,2,-2,1994-03-16
xyz,1,2,3,1994-05-02
对不起大家。
答案1
sed -r 's/(\d{1,2})-([0-9]{2})-([0-9]{4})/\3-\2-\1/g'
似乎可以解决问题,但可能还有其他“更聪明”的方法……我不知道
我的代码:
x="abc,0,2,-2,3-16-1994#xyz,1,2,3,10-09-1994"
echo $x |tr '#' '\n'| sed -r 's/([0-9]{1,2})-([0-9]{2})-([0-9]{4})/\3-\2-\1/g'
生成:
abc,0,2,-2,1994-16-3
xyz,1,2,3,1994-09-10
对您的数据的 2 个“警告”...有点不一致(可能只是为了举例)...
- 在第一行,日期的第一个元素不是“零填充”
- 看了第二行之后,不清楚输入数据是
dd-mm-yyyy
还是mm-dd-yyyy
稍后编辑:我首先错过了填充一天是必需的部分,考虑到这一点,以下内容似乎有帮助
echo $x |tr '#' '\n'| sed -r 's/\b([0-9])-([0-9]{2})-([0-9]{4})\b/\3-\2-0\1/g; s/\b([0-9]{2})-([0-9]{2})-([0-9]{4})\b/\3-\2-\1/g'
实际上我们有 2 个正则表达式,一个(第一个)匹配只有 1 位数字的“日期”,并在替换时添加填充“0”,另一个匹配有 2 位数字的“日期”,并且仅对元素进行重新排序
从这里得到的想法https://stackoverflow.com/questions/12129382/add-leading-0-in-sed-substitution,所以对回答这个问题的人表示感谢
答案2
我测试时发现这个方法有效,请注意,我交换了日期和月份,因为示例中的原始格式实际上是 mm-dd-yyy。不确定零填充对您是否重要,还没有尝试过:
sed -i -r 's|([[:digit:]]*)-([[:digit:]]*)-([[:digit:]]*)|\3-\1-\2|' test.csv