我有这个文件,其中第七个字段是 yyyymmddhhmmss。我需要将这个数字增加一秒。
到目前为止,我已经想出了:
awk 'BEGIN{FS=OFS="|"} $7=$7+1 ' <file>
它有点工作,但是......如果第七个字段的最后两位数字是“59”,它显然会替换为“60”。
有什么方法可以让 awk 知道该字段是日期,这样我就可以将整个列增加一秒?
当前文件
09099458|1|000|41181|0|0|20221130164738|67
82060649|1|000|36827|0|0|20221130172359|67
预期结果
09099458|1|000|41181|0|0|20221130164739|67
82060649|1|000|36827|0|0|20221130172400|67 <- From 17:23:59 to 17:24:00
提前致谢。
答案1
使用 GNUawk
或@托马斯迪基的mawk
1:
$ gawk -F'|' -v OFS='|' '{
gsub("..", "& ", $7)
sub(" ", "", $7)
$7 = strftime("%Y%m%d%H%M%S", mktime($7) + 1)
print}' < your-file
09099458|1|000|41181|0|0|20221130164739|67
82060649|1|000|36827|0|0|20221130172400|67
该gsub()
调用变成"20221130164739"
,"20 22 11 30 16 47 39 "
删除sub()
第一个空格以获得"2022 11 30 16 47 39 "
期望的格式mktime()
。后者将其转换为 UNIX 纪元时间。我们添加 1 并将其重新格式化为 YYYYmmddHHMMSS。
如果您awk
不支持mktime()
/ strftime()
,您可以随时使用perl
及其核心Time::Piece
模块:
perl -MTime::Piece -F'\|' -lase '
$F[6] = (Time::Piece->strptime($F[6], $format) + 1) -> strftime($format);
print join "|", @F' -- -format=%Y%m%d%H%M%S < your-file
在这里,我们依靠与标准 C 函数类似的同名函数来将输入字符串解析为日期Time::Piece
。strptime()
这使得该解决方案更容易适应其他日期格式(除了更便携之外)。
如果您既没有gawk
、mawk
也没有perl
,某些 shell(例如 zsh 或 ksh93)具有对日期/时间解析和格式化的内置支持。
例如,在 中zsh
,这可能是:
zmodload zsh/datetime
format=%Y%m%d%H%M%S
while IFS='|' read -ru3 -A fields; do
strftime -rs t $format $fields[7] &&
strftime -s 'fields[7]' $format $(( t + 1 ))
print -r -- ${(j[|])fields}
done 3< your-file
1 自20121129版本截至撰写本文时,发布时间几乎正好是 10 年前。