我正在尝试获取带有一堆字段的管道分隔文本文件的内容。字段 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
以获得更短的解决方案,单引号内的换行符是可选的。