linux更改文件中的日期格式与全年

linux更改文件中的日期格式与全年

我正在尝试更改全年文件中的日期格式。这是我的数据。

06/30/21 07/01/21 05436841182400056721972 random text
07/06/21 07/07/21 05436841188400057034635 random text
07/17/21 07/19/21 05410191199637000037473 random text
07/21/21 07/22/21 55483821203091001733933 random text
07/24/21 07/26/21 55457021206837001077531 random text

这就是我希望数据的样子。

06/30/2021 07/01/2021 05436841182400056721972 random text
07/06/2021 07/07/2021 05436841188400057034635 random text
07/17/2021 07/19/2021 05410191199637000037473 random text
07/21/2021 07/22/2021 55483821203091001733933 random text
07/24/2021 07/26/2021 55457021206837001077531 random text

不能像我想要的那样进行大规模替换,因为 21 位于文件中的各个位置。

sed 's/21/2021/' junk_dates1
06/30/2021 07/01/21 05436841182400056721972 random text
07/06/2021 07/07/21 05436841188400057034635 random text
07/17/2021 07/19/21 05410191199637000037473 random text
07/2021/21 07/22/21 55483821203091001733933 random text
07/24/2021 07/26/21 55457021206837001077531 random text

不知道如何使用锚点技巧,因为日期后面有数据。

sed 's/21$/2021/' junk_dates1
06/30/21 07/01/21 05436841182400056721972 random text
07/06/21 07/07/21 05436841188400057034635 random text
07/17/21 07/19/21 05410191199637000037473 random text
07/21/21 07/22/21 55483821203091001733933 random text
07/24/21 07/26/21 55457021206837001077531 random text

答案1

$ sed -E -e 's=^([0-9]{2})/([0-9]{2})/([0-9]{2}) ([0-9]{2})/([0-9]{2})/([0-9]{2}) =\1/\2/20\3 \4/\5/20\6 =' input.txt 
06/30/2021 07/01/2021 05436841182400056721972 random text
07/06/2021 07/07/2021 05436841188400057034635 random text
07/17/2021 07/19/2021 05410191199637000037473 random text
07/21/2021 07/22/2021 55483821203091001733933 random text
07/24/2021 07/26/2021 55457021206837001077531 random text

这适用于任何需要以 为前缀的两位数年份20,包括21。它使用 6 个捕获组来捕获第一个和第二个空格分隔字段的日、月和年数字。

21顺便说一句,请注意正则表达式中 两个 s 之后的空格字符。那是您需要的“锚点”(或消歧点或识别标记或任何您想称呼的名称) - 您需要寻找的不仅仅是“21”,而是“21 和一个空格”。有点儿。这并不完全是我最终所做的(一个长匹配模式,多个捕获组锚定在行的开头,^),但这是我开始考虑如何匹配不在末尾的 2 位数年份的地方一条线。

但请注意,虽然这解决了您的问题之一,但它使 MM/DD/YYYY 和 DD/MM/YYYY 日期格式固有的歧义问题永久化。请改用基于 ISO 8601、YYYY-MM-DD 的日期。例如:

$ sed -E -e 's=^([0-9]{2})/([0-9]{2})/([0-9]{2}) ([0-9]{2})/([0-9]{2})/([0-9]{2}) =20\3-\1-\2 20\6-\4-\5 =' input.txt 
2021-06-30 2021-07-01 05436841182400056721972 random text
2021-07-06 2021-07-07 05436841188400057034635 random text
2021-07-17 2021-07-19 05410191199637000037473 random text
2021-07-21 2021-07-22 55483821203091001733933 random text
2021-07-24 2021-07-26 55457021206837001077531 random text

顺便说一句,使用 perl 正则表达式会更容易阅读,\d\d而不是使用[0-9]{2}

$ perl -pe 's=^(\d\d)/(\d\d)/(\d\d) (\d\d)/(\d\d)/(\d\d) =20$3-$1-$2 20$6-$4-$5 =' input.txt 
2021-06-30 2021-07-01 05436841182400056721972 random text
2021-07-06 2021-07-07 05436841188400057034635 random text
2021-07-17 2021-07-19 05410191199637000037473 random text
2021-07-21 2021-07-22 55483821203091001733933 random text
2021-07-24 2021-07-26 55457021206837001077531 random text

不幸的是,没有多少版本能够sed理解 perl 的\d.我唯一知道的是超级sed它有一个-R选项告诉它使用 perl 正则表达式语法:

ssed -R 's=^(\d\d)/(\d\d)/(\d\d) (\d\d)/(\d\d)/(\d\d) =20\3-\1-\2 20\6-\4-\5 =' input.txt

如果您在 Debian 上运行,它就在ssed软件包中。它也可以打包用于其他发行版。无论哪种方式,与仅使用perl -por相比并没有真正的任何好处perl -n

答案2

我建议这个

$ sed 's;\(../../\)21;\12021;g' foo.txt
06/30/2021 07/01/2021 05436841182400056721972 random text
07/06/2021 07/07/2021 05436841188400057034635 random text
07/17/2021 07/19/2021 05410191199637000037473 random text
07/21/2021 07/22/2021 55483821203091001733933 random text
07/24/2021 07/26/2021 55457021206837001077531 ransom text

  • \(../../\)21斜杠括号\(...\)捕获模式char char slash char char slash,该模式在替换 by 中被引用\1。模式 is 之后21,被 替换2021

有了选项-E--regexp-extended)就更清楚了:$ sed 's;(../../)21;\12021;g'

答案3

假设要插入的字符位置(15 和 6)20始终相同:

sed 's/.\{15\}/&20/;s/.\{6\}/&20/' file
06/30/2021 07/01/2021 05436841182400056721972 random text
07/06/2021 07/07/2021 05436841188400057034635 random text
07/17/2021 07/19/2021 05410191199637000037473 random text
07/21/2021 07/22/2021 55483821203091001733933 random text
07/24/2021 07/26/2021 55457021206837001077531 random text

答案4

$ sed 's:/\(.. \):/20\1:g' file
06/30/2021 07/01/2021 05436841182400056721972 random text
07/06/2021 07/07/2021 05436841188400057034635 random text
07/17/2021 07/19/2021 05410191199637000037473 random text
07/21/2021 07/22/2021 55483821203091001733933 random text
07/24/2021 07/26/2021 55457021206837001077531 random text

您确实应该考虑将日期格式更改为 YYYY/MM/DD 或类似格式,因为它更容易使用,例如您可以将该格式的日期作为字符串进行排序和比较:

$ sed 's:\(.....\)/\(..\) :20\2/\1 :g' file
2021/06/30 2021/07/01 05436841182400056721972 random text
2021/07/06 2021/07/07 05436841188400057034635 random text
2021/07/17 2021/07/19 05410191199637000037473 random text
2021/07/21 2021/07/22 55483821203091001733933 random text
2021/07/24 2021/07/26 55457021206837001077531 random text

或 ISO 8601 标准:

$ sed 's:\(..\)/\(..\)/\(..\):20\3-\1-\2:g' file
2021-06-30 2021-07-01 05436841182400056721972 random text
2021-07-06 2021-07-07 05436841188400057034635 random text
2021-07-17 2021-07-19 05410191199637000037473 random text
2021-07-21 2021-07-22 55483821203091001733933 random text
2021-07-24 2021-07-26 55457021206837001077531 random text

相关内容