如何用sed对date/time进行分组?

How to use sed to group date/time?

我有一条短信

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]\)/|\/\/  /p" filename 

但有些文字没有改变

使用您展示的示例,请尝试执行以下 sed 程序。

sed -E 's/(.*\|)([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}:[0-9]{2}:[0-9]{2})-.*/\/\/ /' 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.

使用sed

$ sed 's/\(.*|\)\([^-]*\)-\([^-]*\)-\([^T]*\)T\([^-]*\).*/\/\/ /' input_file
7304628626|duluth/superior|18490|2016|volvo|gas|49230|automatic|sedan|white|mn|46.815216|-92.178109|10/04/2021 08:46:33

\(.*|\) - 匹配直到最后一次出现 | 管道符号

\([^-]*\) - 匹配直到下一次出现 - 斜杠。存储 202104,可以用 </code> 和 <code> 反向引用 return 编辑

\([^T]*\) - 匹配到 T 大写字母 T 的下一次出现。存储 10 可以 return 使用 </code> 反向引用 </p> <p><code>T - 排除 T

\([^-]*\) - 匹配直到下一次出现 - 斜线。存储 08:46:33,可以 return 编辑 </code> 反向引用 </p> <p><code>.* - 排除所有其他内容

如果您的意图是 return 只有日期和时间,您可以删除第一个向后引用

$ sed 's/\(.*|\)\([^-]*\)-\([^-]*\)-\([^T]*\)T\([^-]*\).*/\/\/ /' input_file
10/04/2021 08:46:33

这可能适合您 (GNU sed):

sed -E 's#\|(....)-(..)-(..)T(..:..:..)-....$#|// #' file

模式匹配并根据需要使用反向引用格式。

N.B。使用 |$ 将模式锚定到该行的最后一个字段以及破折号、冒号和大写字母 T 的性质使得任何其他字符串都不太可能匹配,因此点可用于匹配数字,但如果您愿意,请将 . 替换为 [0-9]。此外,# 在替换命令 s#...#...# 中用作正常 / 的替代定界符,因为 / 出现在替换字符串中。