-
-
Save ewaldbenes/0067b79250b4dc65591bc606325ce90e to your computer and use it in GitHub Desktop.
| #!/bin/bash | |
| # Usage: ./trim-icalendar-ics foo-bar.ics 2024 06 | |
| # Removes all events before 2024 and month May (or keeps everything from May 2024 onwards) | |
| # and saves the remaining events into the file foo-bar.ics.out | |
| # Note: current working directory must be the one where the ics file resides! | |
| # Note for Mac and BSD users: this script requires the GNU version of csplit and sed! | |
| # first argument - the calendar file. | |
| # second argument - the year like 2024. | |
| # third argument - the month as 01,02,03,...,09,10,11,12. | |
| CALENDAR_FILE="$1" | |
| YEAR="$2" | |
| MONTH="$3" | |
| temp_dir=temp | |
| temp_files_digits=5 | |
| mkdir -p $temp_dir | |
| cd $temp_dir | |
| # split the calendar file into separate files for each event. This script creates multiple files in the form of xx00000 | |
| total_files=`csplit -n $temp_files_digits ../"$CALENDAR_FILE" '/BEGIN:VEVENT/' {*} | wc -l` | |
| echo "total events found: " $total_files | |
| # filters the split event files by year and month and reassembles the remaining ones into one file | |
| grep -R DTSTART . \ | |
| | sed -s "s/\.\/\(xx[0-9]\+\).*:\([0-9]\{4\}\)\([0-9]\{2\}\).*/\1 \2 \3/g" \ | |
| | awk -v year="$YEAR" -v month="$MONTH" '{if($2>year || ($2==year && $3>=month)) print $1;}' \ | |
| | xargs -L 1 cat > events | |
| # creates the final shrunk ics file with the header and footer files | |
| cat xx00000 events xx`printf "%05d" $((total_files-1))` > ../"$CALENDAR_FILE".out | |
| cd .. | |
| rm -r $temp_dir |
Thanks for pointing out the error @szpak! I will correct the script.
Hi there! Thanks for the useful script.
I encountered a problem when using it: sometimes, the attribute DSTART was spread into two lines, probably when the timezone information is too long, for example in:
BEGIN:VEVENT
LAST-MODIFIED:20240108T131530Z
0100000007B29D3DF1AD815479E335748BED212EA
SUMMARY:FOO
PRIORITY:5
STATUS:CONFIRMED
DTSTART;TZID="(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna"
:20240517T160000
DTEND;TZID="(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna":2
0240517T170000
DESCRIPTION;LANGUAGE=sv-SE:BAR
CLASS:PUBLIC
END:VEVENTIn this case, the ICS file seems to have automatic line break every 75 characters...
I am not a sed expert, @ewaldbenes would you know how to allow for multiple lines?
For my use case, I will handle by hand.
You are correct, @maelmadon; RFC 5545 recommends line folding above 75 octets.
Regarding timezones, this script is strictly limited to DTSTART:2023... formats and does not handle complex datetime strings. Adding full iCal compliance would significantly increase the script's complexity.
While this implementation suffices for my specific requirements, production environments should use a dedicated library. For JS/TS, I recommend ical.js.
Agreed. Thanks for the quick answer!
Thanks for the new version of the script @ewaldbenes! However, there is a logical error in:
It filters out also the events from the further years, if a month is earlier. There should be something like: