ICS文件短格式DTEND日期减一天的Bash脚本问题排查
处理ICS文件中DTEND短格式日期减一天的Bash脚本
直接用数字减法处理日期很容易踩月份/年份边界的坑(比如1月1日减一天要变成前一年的12月31日),用系统自带的date命令来处理日期计算是最靠谱的方案,结合awk可以高效完成需求:
脚本实现
awk '/^DTEND:DATE:/ { # 判断是否为短格式日期(无T,仅8位数字) if ($0 ~ /DTEND:DATE:[0-9]{8}$/) { # 拆分出日期字符串 split($0, seg, ":") raw_date = seg[3] # 调用date命令计算前一天的日期,注意区分系统: # --- Linux(GNU date)用这行 --- cmd = "date -d \"" raw_date " -1 day\" +%Y%m%d" # --- macOS(BSD date)替换成这行 --- # cmd = "date -j -f %Y%m%d " raw_date " -v-1d +%Y%m%d" cmd | getline new_date close(cmd) print "DTEND:DATE:" new_date } else { # 长格式日期直接输出 print $0 } next } # 其他所有行原样输出 { print }' input.ics > output.ics
工作说明
- 仅匹配以
DTEND:DATE:开头的行,其他行直接原样输出 - 对匹配到的行,判断是否是短格式(结尾为8位数字,不含
T) - 提取短格式的日期字符串,通过
date命令计算前一天的日期,并格式化为YYYYMMDD格式 - 长格式的
DTEND行(包含T和时分秒)直接保留原样 - 处理后的内容输出到
output.ics,原文件不会被修改
测试示例
输入片段:
SUMMARY:年度复盘会 DTSTART:DATE:20240101 DTEND:DATE:20240102 SUMMARY:项目评审会 DTSTART:DATE:20240228T140000 DTEND:DATE:20240228T160000
处理后输出:
SUMMARY:年度复盘会 DTSTART:DATE:20240101 DTEND:DATE:20240101 SUMMARY:项目评审会 DTSTART:DATE:20240228T140000 DTEND:DATE:20240228T160000
注意事项
- 不同系统的
date命令语法有差异,一定要根据自己的系统选择对应的cmd行 - 如果需要批量处理多个ICS文件,可以用循环遍历文件列表,替换脚本中的
input.ics为遍历的文件名 - 处理前建议备份原ICS文件,避免意外修改
内容的提问来源于stack exchange,提问作者Dino Kuches
相关产品推荐
相关产品推荐

