使用 bash 解析 ICS 文件



这是一个谷歌日历 ics 文件。

每次都下载它以检查是否已添加或更改新的播放事件,并且我出现在IRC上。

我需要转换这样的文件:

BEGIN:VEVENT
DTSTART:20160612T201000Z
DTEND:20160612T211000Z
DTSTAMP:20160519T200239Z
UID:xxxxxxxxxxxxxxxxxx@google.com
CREATED:20160518T153226Z
DESCRIPTION:
LAST-MODIFIED:20160518T153226Z
LOCATION:OCS Choc
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Ash vs Evil Dead Saison 1 Episode 9 & 10
TRANSP:OPAQUE
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Brussels:20160611T203500
DTEND;TZID=Europe/Brussels:20160611T233500
DTSTAMP:20160519T202440Z
UID:xxxxxxxx@google.com
RECURRENCE-ID;TZID=Europe/Brussels:20160611T203500
CREATED:20160503T144152Z
DESCRIPTION:
LAST-MODIFIED:20160518T123213Z
LOCATION:RTS Un (Suisse)
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:The Mysteries Of Laura Saison 2 Episode 1 à 4
TRANSP:TRANSPARENT
END:VEVENT

New Events Created :
dim. juin 12  20:10  Ash vs Evil Dead Saison 1 Episode 9 & 10 - OCS Choc
Last Modified Event :
sam. juin 11  20:35  The Mysteries Of Laura Saison 2 Episode 1 à 4 - RTS Un (Suisse)

我需要使用 bash 脚本进行转换。我必须得到:

嘟嘟��创建上次修改时间位置总结

我需要比较已创建和上次修改

伪代码 :

if (created = LastModified)
then 
     echo createdevent
else
     echo lastModifiedEvent
fi

本机 bash 实现(对于 shell 版本 4.0 或更高版本 - 旧版本缺少关联数组)如下所示:

#!/bin/bash
handle_event() {
  : # put a definition of your intended logic here
}
declare -A content=( ) # define an associative array (aka map, aka hash)
declare -A tzid=( )    # another associative array for timezone info
while IFS=: read -r key value; do
  value=${value%$'r'} # remove DOS newlines
  if [[ $key = END && $value = VEVENT ]]; then
    handle_event # defining this function is up to you; see suggestion below
    content=( )
    tzid=( )
  else
    if [[ $key = *";TZID="* ]]; then
      tzid[${key%%";"*}]=${key##*";TZID="}
    fi
    content[${key%%";"*}]=$value
  fi
done

。其中handle_event是一个执行您关心的实际工作的函数。例如,这可能看起来像这样:

local_date() {
  local tz=${tzid[$1]}
  local dt=${content[$1]}
  if [[ $dt = *Z ]]; then
    tz=UTC
    dt=${dt%Z}
  fi
  shift
  if [[ $dt = *T* ]]; then
    dt="${dt:0:4}-${dt:4:2}-${dt:6:2}T${dt:9:2}:${dt:11:2}"
  else
    dt="${dt:0:4}-${dt:4:2}-${dt:6:2}"
  fi
  # note that this requires GNU date
  date --date="TZ="$tz" $dt" "$@"
}
handle_event() {
  if [[ "${content[LAST-MODIFIED]}" = "${content[CREATED]}" ]]; then
    echo "New Event Created"
  else
    echo "Modified Event"
  fi
  printf '%st' "$(local_date DTSTART)" "${content[SUMMARY]}" "${content[LOCATION]}"; echo
}

使用您给定的输入文件和上述脚本,bash parse-ics <test.ics 会产生以下输出(使用我当前的区域设置、时区和语言):

New Event Created
Sun Jun 12 15:10:00 CDT 2016    Ash vs Evil Dead Saison 1 Episode 9 & 10        OCS Choc
Modified Event
Sat Jun 11 15:35:00 CDT 2016    The Mysteries Of Laura Saison 2 Episode 1 à 4   RTS Un (Suisse)
awk对于

这样的东西很有用。以下内容可以放在新文件 (ics.awk) 中:

BEGIN{OFS=" "}
$1=="DTSTART"{DTSTART=$2}
$1=="CREATED"{CREATED=$2}
$1=="LAST-MODIFIED"{LASTMODIFIED=$2}
$1=="SUMMARY"{SUMMARY=$2}
$1=="LOCATION"{LOCATION=$2}
$1=="END"{
        if (CREATED==LASTMODIFIED)
                print "nNew Event Created"
        else
                print "nLast Modified Event"
        print DTSTART,SUMMARY,LOCATION
}

您可以像以下方式执行它:

awk -F":" -f ics.awk yourfile.ics

这将用冒号拆分文件中的字段,awk 脚本逐行处理文件。它在找到值时捕获值,然后在找到带有"END"的行时打印它们。

上面的脚本将使您接近:

New Event Created
20160612T201000Z Ash vs Evil Dead Saison 1 Episode 9 & 10 OCS Choc
Last Modified Event
20160612T201000Z The Mysteries Of Laura Saison 2 Episode 1 à 4 RTS Un (Suisse)

使用与@JNevill相同的逻辑,但使用关联数组:

ics.awk

BEGIN { FS=":" }
{ a[$1] = $2 }
$1 == "END" {
  printf("%sn%s %s %snn", 
    a["CREATED"] == a["LAST-MODIFIED"] ? "New Event Created" : "Last Modified Event", 
    a["DTSTART"], a["SUMMARY"], a["LOCATION"])
} 

然后用:

% awk -f ics.awk input-file
New Event Created
20160612T201000Z Ash vs Evil Dead Saison 1 Episode 9 & 10 OCS Choc
Last Modified Event
20160612T201000Z The Mysteries Of Laura Saison 2 Episode 1 Ã  4 RTS Un (Suisse)

但是会留下一个尾随的新行。

$ pip install mutt-ics
$ mutt-ics event.ics
Subject:  DCP IP Seminar 2023
Start:    Friday, 26 May 2023, 08:30 CEST
End:      Friday, 26 May 2023, 17:00 CEST
Location: Auberge du Pêcheur (Pontstraat 41, 9831 Sint-Martens-Latem)

下面是有关创建text/calendar MIME 类型以使用图形电子邮件客户端进行处理的详细信息。

相关内容

  • 没有找到相关文章

最新更新