在 Awk 中使用 gsub 通过正则表达式重新格式化日期

Reformat date through regex expressions with gsub in Awk

提问人:sasa.asa 提问时间:10/9/2023 最后编辑:tripleeesasa.asa 更新时间:10/10/2023 访问量:104

问:

我想在 Awk 中使用 gsub 将日期从 DD/MM/YYYY 重新格式化为 YYYY-MM-DD。

我使用了以下命令:

awk '{gsub(/([0-9]{2})\/([0-9]{2})\/([0-9]{4})/, "([0-9]{4})\-([0-9]{2})\-([0-9]{2})", $4)}1' OFS='       ' example.tsv > example_date.tsv

在输入文件上:

No  Name    LastName    Date    
1   Jane    Doe         24/05/1978  
2   James   Cook        04/04/1974  
3   Jack    Smith       24/05/1978
4   John    Beck        20/10/1980

输出文件与输入文件完全相同。我想知道这里可以改变什么。example_date.tsv

日期 awk gsub

评论

0赞 Wiktor Stribiżew 10/9/2023
年份部分包含 2 位数字,但在您的模式中,您有 .此外,您在替换中没有使用反向引用,您只是将正则表达式放回那里,无论如何,它们不受 .你需要 GNU awk 。[0-9]{4}awksubgensub
2赞 Wiktor Stribiżew 10/9/2023
所以,像这样awk '{$4=gensub(/([0-9]{2})\/([0-9]{2})\/([0-9]{2})/, "\\3-\\2-\\1", "g", $4)}1' file
0赞 jhnc 10/9/2023
你如何在 2014 年和 1914 年之间决定 YY=14 ?
1赞 sasa.asa 10/9/2023
非常感谢@WiktorStribiżew!{4}部分是在这里编写有问题的代码时的错误,在我使用{2}的终端中,我缺少的是 gensub 而不是 gsub。直到现在我才听说过,太神奇了!再次非常感谢你,超级有帮助。
0赞 sasa.asa 10/9/2023
@jhnc这是虚拟文件,在实际文件中年份是“YYYY”格式(这就是为什么我在用 {4} 而不是 {2} 输入上面的代码时犯了一个错误)。

答:

3赞 RavinderSingh13 10/9/2023 #1

对于您显示的示例,请尝试在 GNU 中遵循。awk

  • 设置(记录分隔符)作为所有行,以获得所需的值,以便根据问题在此处进行编辑。RS[[:space:]]+[0-9]+\\/[0-9]+\\/[0-9]+(\\s+|$)
  • 然后检查值是否为 NULL,使用函数获取捕获组中 RT 的值,以便稍后根据 OP 的要求更改其顺序。RTmatch
awk -v RS='[[:space:]]+[0-9]+\\/[0-9]+\\/[0-9]+(\\s+|$)' '
RT && sub(/\n+$/,"",RT){
  match(RT,/^([[:space:]]+)([^/]+)\/([^/]+)\/([0-9]+)(.*)$/,arr)
  print $0 arr[1] arr[4] "/" arr[3] "/" arr[2] arr[5]
}
' Input_file
3赞 markp-fuso 10/9/2023 #2

假设:

  • OP 的真实数据包含格式的日期(根据 OP 的评论)YYYY
  • 输入/输出字段分隔符是制表符 (\t)

设置:

$ cat example.tsv
No      Name    LastName        Date
1       Jane    Doe     24/05/1978
2       James   Cook    04/04/1974
3       Jack    Smith   24/05/1978
4       John    Beck    20/10/1980

一个想法:awk

awk '
BEGIN { FS=OFS="\t" }
NR>1  { split($4,a,"/")                       # split 4th field on "/" delimiter and place in array a[]
        $4 = a[3] "-" a[2] "-" a[1]           # rebuild 4th field in YYYY-MM-DD format
      }
1
' example.tsv

这将产生:

No      Name    LastName        Date
1       Jane    Doe     1978-05-24
2       James   Cook    1974-04-04
3       Jack    Smith   1978-05-24
4       John    Beck    1980-10-20

假设:

  • 输入字段分隔符为空格(可以是空格、制表符或混合);OP 的示例数据显示为固定宽度
  • OP 的正则表达式仅在第 4 列上匹配gsub()

设置:

$ cat example.tsv
No    Name      LastName    Date
1     Jane      Doe         24/05/1978
2     James     Cook        04/04/1974
3     Jack      Smith       24/05/1978
4     John      Beck        20/10/1980

一个想法:awk

awk '
{ split($4,a,"/")
  gsub(/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/,a[3] "-" a[2] "-" a[1])
}
1
' example.tsv

这将产生:

No    Name      LastName    Date
1     Jane      Doe         1978-05-24
2     James     Cook        1974-04-04
3     Jack      Smith       1978-05-24
4     John      Beck        1980-10-20