I have this bash script that fetches calendar event data from a specified ICS (iCalendar) URL and displays events for the current date. The start and end of the events is displayed in the ics format. I have not idea how I can convert the ics format to the YYYY:MM:DD:HH:mm format.
Here is my script:
# Define the ICS URL of your calendar
ics_url="your_url"
# Get today's date in YYYYMMDD format
today=$(date +%Y%m%d)
# Use curl to fetch the ICS data and process it
curl -s "$ics_url" | awk -v date="$today" '
BEGIN {
inEvent = 0;
matched = 0;
eventBuffer = "";
}
/BEGIN:VEVENT/ {
inEvent = 1;
matched = 0;
eventBuffer = ""; # Reset event buffer at the beginning of a new event
}
/END:VEVENT/ {
if (matched) {
print eventBuffer; # Print the event buffer if matched
print ""; # Print an empty line after each event
}
inEvent = 0;
}
/^DTSTART:/ {
if (index($0, date) > 0) {
matched = 1;
}
# Replace "DTSTART" with "start"
sub(/^DTSTART:/, "start:", $0);
eventBuffer = eventBuffer "\n" $0;
}
/^DTEND:/ {
# Replace "DTEND" with "end"
sub(/^DTEND:/, "end:", $0);
eventBuffer = eventBuffer "\n" $0;
}
/^SUMMARY|DESCRIPTION/ {
eventBuffer = eventBuffer "\n" $0;
}
'
Example output:
start:20240502T080000Z
end:20240502T090000Z
SUMMARY:Event
Desired output:
start:2024:05:02:08:00:00
end:2024:05:02:09:00:00
SUMMARY:Event
or
start:08:00
end:09:00
SUMMARY:Event
I found a solution. Thanks for all the answers. They helped a lot.
ics_url="your_url"
# Get today's date in YYYYMMDD format
today=$(date +%Y%m%d)
# Use curl to fetch the ICS data and process it
curl -s "$ics_url" | awk -v date="$today" '
BEGIN {
inEvent = 0;
matched = 0;
}
/BEGIN:VEVENT/ {
inEvent = 1;
matched = 0; # Reset the matched flag at the beginning of a new event
start = ""; # Reset variables at the start of a new event
end = "";
summary = "";
}
/END:VEVENT/ {
if (matched) {
# Extract hour and minute from start and end variables
start1 = substr(start, 10, 2);
start2 = substr(start, 12, 2);
end1 = substr(end, 10, 2);
end2 = substr(end, 12, 2);
# Output the data in the specified order
print "Event: " summary;
print "start: " start1 ":" start2;
print "end: " end1 ":" end2;
print ""; # Print an empty line to separate events
}
inEvent = 0;
}
/^DTSTART:/ {
if (index($0, date) > 0) {
matched = 1;
}
# Store the start time without the label
sub(/^DTSTART:/, "", $0);
if (matched) {
start = $0;
}
}
/^DTEND:/ {
# Store the end time without the label
sub(/^DTEND:/, "", $0);
if (matched) {
end = $0;
}
}
/^SUMMARY:/ {
# Store the summary without the label
sub(/^SUMMARY:/, "", $0);
if (matched) {
summary = $0;
}
}'
New Output:
Event: Meeting
start: 10:30
end: 11:30
Event: Go for a walk
start: 10:00
end: 10:30
The following update should solve your requirement:
# Define the ICS URL of your calendar
ics_url="your_url"
# Get today's date in YYYYMMDD format
today=$(date +%Y%m%d)
# Use curl to fetch the ICS data and process it
curl -s "$ics_url" | awk -v date="$today" '
BEGIN {
inEvent = 0;
matched = 0;
eventBuffer = "";
}
/BEGIN:VEVENT/ {
inEvent = 1;
matched = 0;
eventBuffer = ""; # Reset event buffer at the beginning of a new event
}
/END:VEVENT/ {
if (matched) {
print eventBuffer; # Print the event buffer if matched
print ""; # Print an empty line after each event
}
inEvent = 0;
}
/^DTSTART:/ {
if (index($0, date) > 0) {
matched = 1;
}
# Replace "DTSTART" with "start"
t = mktime(substr($0,9,4) " " substr($0,13,2) " " substr($0,15,2) " " substr($0,18,2) " " substr($0,20,2) " " substr($0,22,2))
line = "start:" strftime("%Y:%m:%d:%H:%M:%S",t)
eventBuffer = eventBuffer "\nstart:" line;
}
/^DTEND:/ {
# Replace "DTEND" with "end"
t = mktime(substr($0,7,4) " " substr($0,11,2) " " substr($0,13,2) " " substr($0,16,2) " " substr($0,18,2) " " substr($0,20,2))
line = strftime("%Y:%m:%d:%H:%M:%S",t)
eventBuffer = eventBuffer "\nend:" line;
}
/^SUMMARY|DESCRIPTION/ {
eventBuffer = eventBuffer "\n" $0;
}
'
Testing with the following input
:
$ cat input.txt
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//iCal4j 1.0//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
DTSTAMP:20240502T120000Z
DTSTART:20240505T090000Z
DTEND:20240505T100000Z
SUMMARY:Team Meeting
DESCRIPTION:Weekly team meeting to discuss progress and upcoming tasks.
LOCATION:Conference Room
UID:1234567890
SEQUENCE:0
END:VEVENT
BEGIN:VEVENT
DTSTAMP:20240502T120000Z
DTSTART:20240510T140000Z
DTEND:20240510T160000Z
SUMMARY:Client Presentation
DESCRIPTION:Present our latest project updates to the client.
LOCATION:Client's Office
UID:0987654321
SEQUENCE:0
END:VEVENT
END:VCALENDAR
The output will be:
start:start:2024:05:05:09:00:00
end:2024:05:05:10:00:00
SUMMARY:Team Meeting
DESCRIPTION:Weekly team meeting to discuss progress and upcoming tasks.
start:start:2024:05:10:14:00:00
end:2024:05:10:16:00:00
SUMMARY:Client Presentation
DESCRIPTION:Present our latest project updates to the client.
I ran it a little bit different ... I have the input as input.txt
, the awk
script as format.awk
:
BEGIN {
inEvent = 0;
matched = 0;
eventBuffer = "";
}
/BEGIN:VEVENT/ {
inEvent = 1;
matched = 0;
eventBuffer = ""; # Reset event buffer at the beginning of a new event
}
/END:VEVENT/ {
if (matched) {
print eventBuffer; # Print the event buffer if matched
print ""; # Print an empty line after each event
}
inEvent = 0;
}
/^DTSTART:/ {
if (index($0, date) > 0) {
matched = 1;
}
# Replace "DTSTART" with "start"
t = mktime(substr($0,9,4) " " substr($0,13,2) " " substr($0,15,2) " " substr($0,18,2) " " substr($0,20,2) " " substr($0,22,2))
line = "start:" strftime("%Y:%m:%d:%H:%M:%S",t)
eventBuffer = eventBuffer "\nstart:" line;
}
/^DTEND:/ {
# Replace "DTEND" with "end"
t = mktime(substr($0,7,4) " " substr($0,11,2) " " substr($0,13,2) " " substr($0,16,2) " " substr($0,18,2) " " substr($0,20,2))
line = strftime("%Y:%m:%d:%H:%M:%S",t)
eventBuffer = eventBuffer "\nend:" line;
}
/^SUMMARY|DESCRIPTION/ {
eventBuffer = eventBuffer "\n" $0;
}
And using CLI:
awk -f format.awk input.txt