sed命令交换字符

sed命令交换字符

我的输入文件布局是:mm/dd/yyyy,hh:mm,other fields
我需要将其格式化为: yyyy-mm-dd hh:mm:00,other fields

示例输入:

01/02/1998,09:30,0.4571,0.4613,0.4529,0.4592,6042175
01/02/1998,09:45,0.4592,0.4613,0.4529,0.4571,9956023
01/02/1998,10:00,0.4571,0.4613,0.455,0.4613,8939555
01/02/1998,10:15,0.4613,0.4697,0.4571,0.4697,12823627
01/02/1998,10:30,0.4676,0.4969,0.4613,0.4906,28145145

示例输出:

1998-01-02 09:30:00,0.4571,0.4613,0.4529,0.4592,6042175
etc...

我尝试使用:

sed -r 's/\(^[0-9][0-9])\(\/[0-9][0-9]\/)\(\/[0-9][0-9][0-9][0-9],)/\3\1\2/g

答案1

sed -e 's/\(..\)\/\(..\)\/\(....\),\(.....\),\(.*\)/\3-\1-\2 \4:00,\5/'

编辑以包含以下评论的输入:

sed -e 's#\(..\).\(..\).\(....\),\(.....\),#\3-\1-\2 \4:00,#'

答案2

这对我有用:

sed -r 's/([0-9]{2})\/([0-9]{2})\/([0-9]{4}),([0-9:]{5})/\3-\1-\2 \4:00/g'

匹配 2 位数字 ( ([0-9]{2}))、斜杠、2 位数字 ( ([0-9]{2}))、斜杠、4 位数字 ( ([0-9]{4})),然后是数字和:( ([0-9:]{5}))。将其替换为您想要的顺序:(\3-\1-\2 \4:00年-月-日时:分:00)。

答案3

sed 'y|/|-|
     s/,*\(.....\)-*\([^,]*\)/\2-\1/
     s// \1:00/2
'    <infile

输出:

1998-01-02 09:30:00,0.4571,0.4613,0.4529,0.4592,6042175
1998-01-02 09:45:00,0.4592,0.4613,0.4529,0.4571,9956023
1998-01-02 10:00:00,0.4571,0.4613,0.455,0.4613,8939555
1998-01-02 10:15:00,0.4613,0.4697,0.4571,0.4697,12823627
1998-01-02 10:30:00,0.4676,0.4969,0.4613,0.4906,28145145

通常sed,您不需要如此努力 - 尝试显式枚举您正在寻找的匹配项通常是没有回报的。相反,通常只需指定一些界标(分隔符)就简单得多,然后让模式为您吞噬过渡。

上面sed首先将字符y///翻译为字符。接下来它引用第一个非逗号/-(前提是至少有5个)模式空间中的字符和接下来的四个字符,\1同时可能忽略尾随-.接下来,在模式空间中下一个出现的逗号之前引用尽可能多的连续^非逗号字符。\2第一次替换的结果是,它在匹配之前mm-dd放入,然后放入。因此,我们交换它们,删除并在另一侧插入一个新的,如下所示:\1-yyyy\2-

s/.../\2-\1/

最后我们再做一次——为不同的目的重复使用相同的模式。当我做:

s// \1:00/2

我指示sed重用最后一个正则表达式(如空地址所示//,但这一次是为了在模式空间中找到该模式的第二次出现 - 其中与此时间匹配逗号,*- 它匹配分隔此字段和最后一个字段的逗号。它还HH:MM匹配\1(因为该字符串后面紧跟着一个逗号)''中的空字符串\2。剩下的就是\1用其自身替换<空格>然后是:00细绳。中间的逗号和空字符串都被编辑掉。

如果你感觉你不过,毕竟更具体一点,考虑一下如果有一点抽象的话可能会容易得多。正则表达式提供的主要好处是,它们为我们提供了一种快速有效地抽象出重复任务的方法,只要首先清楚地了解是什么导致了重复任务。

如果构建正则表达式本身就成为一项重复性任务,那么,好吧......可能缺少某些东西。不过,简单正则表达式语法的优点之一是它通常是抽象的一个很好的候选者——而且很容易实现。

例如:

d='[0-9][0-9]' T=$d:$d m=$d y=$d$d
sed -E "s|($m/$d)/($y),($T)|\2-\1 \3:00|;s|/|-|"

答案4

以及可能的awk解决方案:

awk 'BEGIN { FS = OFS = ","; } { split($1, d, "/"); $2 = d[3] "-" d[1] "-" d[2] " " $2 ":00"; $1 = ""; } { for (i = 2; i < NF; i++) printf("%s", $i OFS); printf("%s", $NF ORS);}' file

相关内容