解析字段的脚本,更改第 n 个字段的格式

解析字段的脚本,更改第 n 个字段的格式

我正在尝试获取带有一堆字段的管道分隔文本文件的内容。字段 10 是时间戳,其格式为yyyy-MM-dd hh:mm:ss, 或yyyy-MM-dd hh:mm:ss.SSS。如果是前者,我想将 a 附加.'000'到该字段的末尾 - 否则我想保留它,并且我想保留其他字段不变。

我目前正在尝试使用awk.它似乎有效,但我的解决方案感觉有点awk病房:-)

awk 'BEGIN {FS=OFS="|"}
{for(i=1;i<9;i++) printf "%s|",$i; printf "%s|",$9}
{printf($10 ~ /\./) ? substr($10,1,10)" "substr($10,12)"|" : substr($10,1,10)" "substr($10,12,18)".000|"}
{for(i=11;i<NF;i++) printf "%s|",$i; printf "%s\n",$NF}'

我能做点什么来整理一下吗?

答案1

应该可以将其简化为“一行”。实际上,您只需要一条规则,如果遇到没有毫秒的时间戳,则修改字段 10,以及一条规则,该规则在一般情况下(包括由于规则 1 而可能进行的修改)简单地“打印”整行。因此,假设GNU Awk

awk -F'|' -v OFS='|' '$10 ~ /^[[:digit:]]{4}(-[[:digit:]]{2}){2} ([[:digit:]]{2}:){2}[[:digit:]]{2}$/ {$10=$10".000"} {print}' textfile

应该可以解决问题。

在大多数情况下,上面的正则表达式在检查时间戳方面过于“彻底”。如果您足够信任您的文件格式,则可以将字段 10 的检查减少为

awk -F'|' -v OFS='|' '$10 ~ /:[0-5][0-9]$/ {$10=$10".000"} {print}'

这也不再需要 GNU 版本awk

将其应用于测试输入

a|b|c|d|e|f|i|j|k|2020-01-20 10:22:33|m|n|o
a|b|c|d|e|f|i|j|k|2020-01-20 10:22:33.123|m|n|o

产量:

~$ awk -F'|' -v OFS='|' '$10 ~ /:[0-5][0-9]$/ {$10=$10".000"} {print}' testinput

a|b|c|d|e|f|i|j|k|2020-01-20 10:22:33.000|m|n|o
a|b|c|d|e|f|i|j|k|2020-01-20 10:22:33.123|m|n|o

答案2

只需更改第 10 个字段即可。

awk 'BEGIN { FS=OFS="|" }
     NF>9 && $10 !~ /\.[0-9][0-9][0-9]$/ {  $10 = $10".000" }
     {print}'

您可以替换{print}1以获得更短的解决方案,单引号内的换行符是可选的。

相关内容