【问题标题】:How to use sed to group date/time?如何使用 sed 对日期/时间进行分组?
【发布时间】:2021-12-25 00:17:15
【问题描述】:
我有一条短信
7304628626|duluth/superior|18490|2016|volvo|gas|49230|automatic|sedan|white|mn|46.815216|-92.178109|2021-04-10T08:46:33-0500
我想把文字2021-04-10T08:46:33-0500改成10/04/2021 08:46:33
我尝试使用这个命令
sed -n "s/|\([0-2][0-9][0-9][0-9]\)-\([0-1][0-9]\)-\([1-3][0-9]\)\(T\)\([0-9][0-9]:[0-9][0-9]:[0-9][0-9]\)\(-[0-1][0-9][0][0]\)/|\3\/\2\/\1 \5 /p" filename
但有些文字没有改变
【问题讨论】:
标签:
unix
sed
command-line
【解决方案1】:
这可能对你有用(GNU sed):
sed -E 's#\|(....)-(..)-(..)T(..:..:..)-....$#|\3/\2/\1 \4#' file
模式匹配并根据需要使用反向引用格式。
注意使用| 和$ 将模式锚定到该行的最后一个字段以及破折号、冒号和大写T 的性质使得任何其他字符串都不太可能匹配,因此可以使用点匹配数字,但如果您喜欢将. 替换为[0-9]。此外,# 在替换命令s#...#...# 中用作普通/ 的替代分隔符,因为/ 出现在替换字符串中。
【解决方案2】:
使用sed
$ sed 's/\(.*|\)\([^-]*\)-\([^-]*\)-\([^T]*\)T\([^-]*\).*/\1\4\/\3\/\2 \5/' input_file
7304628626|duluth/superior|18490|2016|volvo|gas|49230|automatic|sedan|white|mn|46.815216|-92.178109|10/04/2021 08:46:33
\(.*|\) - 匹配直到最后一次出现 | 管道符号
\([^-]*\) - 匹配到下一次出现- 斜线。存储 2021 和 04 可以使用 \2 和 \3 反向引用返回
\([^T]*\) - 匹配直到下一次出现 T 大写 T。存储 10 可以使用 \4 反向引用返回
T - 排除T
\([^-]*\) - 匹配直到下一次出现 - 斜线。存储 08:46:33 可以使用 \5 反向引用返回
.* - 排除其他所有内容
如果您的意图是只返回日期和时间,您可以删除第一个反向引用
$ sed 's/\(.*|\)\([^-]*\)-\([^-]*\)-\([^T]*\)T\([^-]*\).*/\4\/\3\/\2 \5/' input_file
10/04/2021 08:46:33
【解决方案3】:
使用您展示的示例,请尝试关注sed 程序。
sed -E 's/(.*\\|)([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}:[0-9]{2}:[0-9]{2})-.*/\1\4\/\3\/\2 \5/' Input_file
解释:在这里使用sed 程序的反向引用功能将匹配的值存储到临时缓冲区中,并在以后使用它们进行替换。在主sed 程序中使用-E 选项启用ERE(扩展正则表达式),然后使用s 选项执行替换。首先创建5个捕获组以匹配7304628626|duluth/superior|18490|2016|volvo|gas|49230|automatic|sedan|white|mn|46.815216|-92.178109|(在第一个捕获组中),2021(在第二个捕获组中),04(在第三个捕获组中),10(在第4个捕获组中)和08:46:33 (在第 5 个捕获组中)。并且根据 OP 需要的顺序替换它们以保持顺序以捕获组,因为 OP 希望将 2021-04-10T08:46:33-0500 更改为 10/04/2021 08:46:33。