Shell脚本中如何将日志文件的日期格式从%Y%m%d%H%M转为%Y-%m-%d %H:%M
解决Shell中日志日期格式转换的问题
针对你需要把logfile.txt第一列的%Y%m%d%H%M%S格式日期(比如20180404132301)转换为%Y-%m-%d %H:%M格式(比如2018-04-04 13:23)的需求,这里有几种高效的实现方式:
方法一:用awk直接字符串截取(最快,适合固定格式)
awk处理列数据非常方便,我们可以直接通过字符串截取来重组日期格式,全程在awk进程内完成,没有外部调用,速度极快:
awk '{ # 从第一列提取各日期字段 year = substr($1, 1, 4) month = substr($1, 5, 2) day = substr($1, 7, 2) hour = substr($1, 9, 2) minute = substr($1, 11, 2) # 重组为目标格式并替换第一列 $1 = year "-" month "-" day " " hour ":" minute # 打印整行,保留其他列内容 print $0 }' logfile.txt
方法二:用sed正则替换(简洁,适合固定长度格式)
sed的正则分组捕获可以一行命令完成替换,写法非常简洁:
sed -E 's/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})[0-9]{2}/\1-\2-\3 \4:\5/' logfile.txt
正则说明:
^匹配行开头,确保只替换第一列的日期([0-9]{4})捕获4位年份,对应替换后的\1([0-9]{2})依次捕获月份、日期、小时、分钟,对应\2到\5[0-9]{2}匹配最后两位秒数,替换时直接忽略- 最终重组为
\1-\2-\3 \4:\5的目标格式
如果需要直接修改原文件,可加上-i选项(建议加备份后缀,比如-i.bak,防止误操作丢失原数据):
sed -i.bak -E 's/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})[0-9]{2}/\1-\2-\3 \4:\5/' logfile.txt
方法三:用date命令校验日期(适合需要合法性检查的场景)
如果担心日志中存在无效日期(比如月份为13、日期为32这类错误),可以调用date命令解析并格式化,同时自动校验日期的合法性:
awk '{ # 截取前12位,去掉秒数,保留YYYYMMDDHHMM格式 raw_dt = substr($1, 1, 12) # 调用date命令生成目标格式 cmd = "date -d \"" raw_dt "\" +\"%Y-%m-%d %H:%M\"" cmd | getline new_dt # 关闭命令管道,避免资源泄漏 close(cmd) # 替换第一列并打印整行 $1 = new_dt print $0 }' logfile.txt
注意:这种方法每行都会启动一个date进程,处理大文件时速度会慢一些,更适合数据量较小或需要日期校验的场景。
内容的提问来源于stack exchange,提问作者Smdevfunia
相关产品推荐
相关产品推荐

