You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PowerShell拆分ICS日历事件及合并去重谷歌ICS文件问题求助

解决PowerShell处理ICS文件时无法将VEVENT作为多行字符串块的问题

你遇到的核心问题是默认Get-Content会把ICS文件拆成逐行的字符串数组,导致后续替换和分割操作都基于单行执行,没法得到完整的VEVENT多行块。我来帮你修正逻辑,同时给出合并两个ICS并去重的完整方案:

第一步:正确读取ICS文件为完整字符串

先避免逐行读取,用-Raw参数一次性把整个ICS文件读成单个字符串,这样后续正则操作才能处理多行内容:

# 读取第一个日历文件
$cal1Content = Get-Content ".\googlecalendar.ics" -Raw
# 读取第二个日历文件
$cal2Content = Get-Content ".\another_calendar.ics" -Raw

第二步:提取所有VEVENT多行块

用正则表达式匹配从BEGIN:VEVENTEND:VEVENT的完整块,其中(?s)是单行模式(让.能匹配换行符),.*?是非贪婪匹配(确保每个匹配都是独立的事件):

# 从第一个日历提取事件块
$events1 = [regex]::Matches($cal1Content, '(?s)BEGIN:VEVENT.*?END:VEVENT') | ForEach-Object { $_.Value }
# 从第二个日历提取事件块
$events2 = [regex]::Matches($cal2Content, '(?s)BEGIN:VEVENT.*?END:VEVENT') | ForEach-Object { $_.Value }
# 合并两个日历的事件列表
$allEvents = $events1 + $events2

现在$allEvents里的每个元素都是完整的多行VEVENT事件字符串,你可以用$allEvents[0]验证,会输出整个事件的内容而非单行。

第三步:移除重复事件

ICS文件的UID字段是事件的唯一标识,我们通过它过滤重复项:

$seenUids = @()
$uniqueEvents = $allEvents | Where-Object {
    # 提取当前事件的UID
    $uidMatch = $_ | Select-String '^UID:' -List
    if ($uidMatch) {
        $uid = $uidMatch.Line -replace '^UID:', ''
        # 若UID未被记录则保留事件,并标记该UID已见过
        if ($seenUids -notcontains $uid) {
            $seenUids += $uid
            $true
        } else {
            $false
        }
    } else {
        # 无UID的事件直接保留(标准ICS一般都会有UID)
        $true
    }
}

第四步:生成合并后的完整ICS文件

保留原ICS的头部信息(比如BEGIN:VCALENDAR、版本信息等),拼接去重后的事件,最后加上结尾:

# 提取第一个日历的头部(从开头到第一个VEVENT之前的内容)
$header = $cal1Content -split '(?=BEGIN:VEVENT)', 2 | Select-Object -First 1
# 拼接成完整的日历内容
$mergedContent = $header + ($uniqueEvents -join "`r`n") + "`r`nEND:VCALENDAR"
# 保存到新文件,用UTF-8编码避免乱码
$mergedContent | Out-File ".\merged_unique_calendar.ics" -Encoding UTF8

这样处理后,你就能得到合并两个日历且移除重复事件的ICS文件了。

内容的提问来源于stack exchange,提问作者umsrato

火山引擎 最新活动