使用awk解析ICS文件为表格遇错误,求助添加表头实现方案
用AWK解析ICS文件生成带表头的表格
我来帮你搞定这个ICS解析的问题!首先咱们明确核心需求:提取ICS中DTSTART、DTEND、CREATED、SUMMARY开头的行,输出成带表头的规整表格。我先给你一个能直接用的AWK脚本,再拆解细节,顺便帮你排查常见错误。
完整AWK脚本
BEGIN { # 打印表头和分隔线,用制表符实现对齐 printf "%-20s\t%-20s\t%-20s\t%s\n", "DTSTART", "DTEND", "CREATED", "SUMMARY" printf "%s\t%s\t%s\t%s\n", "--------------------", "--------------------", "--------------------", "------------------------" # 初始化存储字段的变量,避免残留上一个事件的内容 dtstart = dtend = created = summary = "" } # 匹配目标行,提取冒号后的内容(注意关键字长度,substr起始位置要准确) /^DTSTART:/ { dtstart = substr($0, 9) } /^DTEND:/ { dtend = substr($0, 7) } /^CREATED:/ { created = substr($0, 9) } /^SUMMARY:/ { summary = substr($0, 9) } # 处理ICS中的续行(如果SUMMARY等字段跨多行,第二行以空格开头) /^ / { if (summary != "") { summary = summary substr($0, 2) # 去掉开头的空格,拼接到原summary } next # 跳过后续处理,直接进入下一行 } # 当遇到单个事件结束标记时,输出当前事件的表格行 /^END:VEVENT/ { printf "%-20s\t%-20s\t%-20s\t%s\n", dtstart, dtend, created, summary # 重置变量,准备处理下一个事件 dtstart = dtend = created = summary = "" } # 处理最后一个事件可能没有END:VEVENT标记的情况 END { if (dtstart != "" || dtend != "" || created != "" || summary != "") { printf "%-20s\t%-20s\t%-20s\t%s\n", dtstart, dtend, created, summary } }
脚本运行方式
把上面的代码保存为parse_ics.awk,然后执行:
awk -f parse_ics.awk 你的日历文件.ics
或者直接用一行命令执行(不用保存文件):
awk 'BEGIN {printf "%-20s\t%-20s\t%-20s\t%s\n", "DTSTART", "DTEND", "CREATED", "SUMMARY"; printf "%s\t%s\t%s\t%s\n", "--------------------", "--------------------", "--------------------", "------------------------"; dtstart=dtend=created=summary=""} /^DTSTART:/ {dtstart=substr($0,9)} /^DTEND:/ {dtend=substr($0,7)} /^CREATED:/ {created=substr($0,9)} /^SUMMARY:/ {summary=substr($0,9)} /^ / {if(summary!="") summary=summary substr($0,2); next} /^END:VEVENT/ {printf "%-20s\t%-20s\t%-20s\t%s\n", dtstart,dtend,created,summary; dtstart=dtend=created=summary=""} END {if(dtstart!=""||dtend!=""||created!=""||summary!="") printf "%-20s\t%-20s\t%-20s\t%s\n", dtstart,dtend,created,summary}' 你的日历文件.ics
常见错误排查
- 字段提取错误:很多人会用
$2取冒号后的内容,但ICS行的冒号后可能有空格或特殊字符,用substr按关键字长度截取更可靠(比如DTSTART:是8个字符,所以从第9位开始截取)。 - 多事件串数据:如果ICS包含多个事件,忘记重置变量会导致前一个事件的字段残留到下一个,脚本里的
/^END:VEVENT/块会自动重置变量,解决这个问题。 - 续行没处理:ICS中长字段(比如SUMMARY)可能拆成多行,第二行以空格开头,脚本里的
/^ /块会把续行内容拼接到原字段。 - 表头对齐混乱:用
printf的格式化输出(%-20s表示左对齐、占20个字符)能让表格更规整,比直接print美观得多。
内容的提问来源于stack exchange,提问作者rororo
相关产品推荐
相关产品推荐

