simplify and improve portability across mawk, gawk, nawk, busybox awk... - ics2… | |
git clone git://bitreich.org/ics2txt git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
--- | |
commit 24985c575e833254adb79215584947a601569ea1 | |
parent c6606df0960a765824c000aeb54e21691bcc94bb | |
Author: Josuah Demangeon <[email protected]> | |
Date: Thu, 25 Jun 2020 21:11:17 +0200 | |
simplify and improve portability across mawk, gawk, nawk, busybox awk... | |
Diffstat: | |
M README | 33 +++++++++++++++--------------… | |
M ics2tsv | 32 ++++++++++++-----------------… | |
M tcal2tsv | 12 ++++++------ | |
M tsv2tcal | 4 ++-- | |
4 files changed, 36 insertions(+), 45 deletions(-) | |
--- | |
diff --git a/README b/README | |
@@ -1,7 +1,5 @@ | |
-ICS2TSV(1) General Commands Manual ICS2TSV(1) | |
- | |
NAME | |
- ics2tsv – convert ics file to simpler tsv or txt formats | |
+ ics2txt – convert ics file to simpler tsv or txt formats | |
SYNOPSIS | |
ics2txt <file.ics >file.txt | |
@@ -13,31 +11,34 @@ SYNOPSIS | |
tsv2ics <file.tsv >file.ics | |
DESCRIPTION | |
- ics2tsv is set of awk scripts to deal with iCal (.ics) format to publish, | |
+ ics2txt is set of awk scripts to deal with iCal (.ics) format to publish, | |
display and convert *.ics files, though a simple central TSV format. | |
They all read from either stdin or the file passed as argument, and write | |
to stdout. | |
- file.tsv files have one line per event, all with the following fields, | |
- separated by one tab: | |
- 1. Begining (epoch) | |
- 2. End (epoch) | |
- 3. Category | |
- 4. Location | |
- 5. Summary | |
- 6. Description | |
+ file.tsv have one line per event, with the first line declaring fields | |
+ order and presence, among: | |
+ “beg” Begining of event (epoch) | |
+ “end” End of event (epoch) | |
+ “cat” Category | |
+ “loc” Location | |
+ “sum” Summary | |
+ “des” Description | |
EXAMPLES | |
- Convert a calendar from HTTP .ics to custom .txt sorted by beginning | |
- date: | |
+ Convert a calendar from HTTP .ics to custom .txt sorted by start date: | |
curl $url.ics | ics2tsv | sort -n -k 1,1 | tsv2txt | |
Convert a custom .txt format back to an .ics file and publish it: | |
tcal2tsv cal.txt | tsv2ics | ssh www@$host 'cat >/var/www/cal.ics' | |
Split an file according to the category, saved as .tsv: | |
- tcal2tsv cal.txt | awk -F '\t' '{ f = $3".tsv"; print >>f }' | |
+ | |
+ ics2tsv cal.txt | awk -F '\t' ' | |
+ NR == 1 { for (i = 1; i <= NF; i++) F[$i] = i; next } | |
+ { print >>($F["cat"]".tsv") } | |
+ ´ | |
SEE ALSO | |
cal(1), calendar(1), date(1), sort(1) | |
@@ -48,5 +49,3 @@ STANDARDS | |
AUTHORS | |
Josuah Demangeon <[email protected]> | |
- | |
-OpenBSD 6.6 March 1, 2020 OpenBSD 6.6 | |
diff --git a/ics2tsv b/ics2tsv | |
@@ -44,49 +44,41 @@ function ical_to_epoch(str, offset, | |
function print_event(ev, fields, | |
i) | |
{ | |
- for (i = 1; i <= fields["len"]; i++) | |
+ for (i = 1; i in fields; i++) | |
printf("%s%s", (i > 1 ? "\t" : ""), ev[fields[i]]) | |
printf("\n") | |
} | |
BEGIN { | |
FIELDS = "DTSTART DTEND CATEGORIES LOCATION SUMMARY DESCRIPTION" | |
- fields["len"] = split(FIELDS, fields, " ") | |
+ split(FIELDS, fields, " ") | |
# by default: "CATEGORIES" -> "cat", "LOCATION" -> "loc"... | |
translate["DTSTART"] = "beg" | |
translate["DTEND"] = "end" | |
- "date +%z" | getline offset_str | |
+ "date +%z" | getline | |
close("date +%z") | |
- hour = substr($0, 4, 2) | |
- min = substr($0, 6, 2) | |
- tzoffset = substr(zone, 3, 1) hour * 3600 + min * 60 | |
+ TZ = substr($0, 3, 1) substr($0, 4, 2)*3600 + substr($0, 6, 2)*60 | |
FS = "[:;]" | |
- for (i = 1; i <= fields["len"]; i++) { | |
+ for (i = 1; i in fields; i++) { | |
if (!(s = translate[fields[i]])) | |
s = tolower(substr(fields[i], 1, 3)) | |
printf("%s%s", (i > 1 ? "\t" : ""), s) | |
} | |
- | |
printf("\n") | |
} | |
+/^ / { | |
+ ev[type] = ev[type] substr($0, 2, length($0) - 1) | |
+ next | |
+} | |
+ | |
{ | |
- gsub("\r", "") | |
- gsub("\t", "\\\\t") | |
- gsub("^ *", "") | |
- gsub(" *$", "") | |
- | |
- if (match($0, "^ ")) { | |
- ev[type] = ev[type] substr($0, 2, length($0) - 1) | |
- } else { | |
- type = $1 | |
- i = index($0, ":") | |
- ev[type] = substr($0, i + 1, length($0) - i) | |
- } | |
+ i = index($0, ":") | |
+ ev[$1] = substr($0, i + 1, length($0) - i) | |
} | |
/^END:VEVENT/ { | |
diff --git a/tcal2tsv b/tcal2tsv | |
@@ -42,9 +42,9 @@ function text_to_epoch(str, tz, | |
BEGIN { | |
FIELDS = "beg end cat loc sum des" | |
- fields["len"] = split(FIELDS, fields, " ") | |
+ split(FIELDS, fields, " ") | |
- for (i = 1; i <= fields["len"]; i++) { | |
+ for (i = 1; i in fields; i++) { | |
pos[fields[i]] = i | |
printf("%s%s", (i > 1 ? "\t" : ""), fields[i]) | |
} | |
@@ -56,16 +56,16 @@ BEGIN { | |
} | |
/^TZ[+-]/ { | |
- TZOFFSET = substr($1, 3, 1) substr($0, 4, 2)*3600 + substr($0, 6, 2)*60 | |
+ TZ = substr($1, 3, 1) substr($0, 4, 2)*3600 + substr($0, 6, 2)*60 | |
while (getline && $0 ~ /^$/) | |
continue | |
} | |
/^[0-9]+-[0-9]+-[0-9]+/ { | |
if ("beg" in ev) | |
- ev["end"] = text_to_epoch($0, TZOFFSET) | |
+ ev["end"] = text_to_epoch($0, TZ) | |
else | |
- ev["beg"] = text_to_epoch($0, TZOFFSET) | |
+ ev["beg"] = text_to_epoch($0, TZ) | |
next | |
} | |
@@ -78,7 +78,7 @@ BEGIN { | |
} | |
/^$/ { | |
- for (i = 1; i <= fields["len"]; i++) | |
+ for (i = 1; i in fields; i++) | |
printf("%s%s", (i > 1 ? "\t" : ""), ev[fields[i]]) | |
printf("\n") | |
delete ev | |
diff --git a/tsv2tcal b/tsv2tcal | |
@@ -43,13 +43,13 @@ function gmtime(sec, tm) | |
function localtime(sec, tm, | |
tz, h, m) | |
{ | |
- return gmtime(sec + TZOFFSET, tm) | |
+ return gmtime(sec + TZ, tm) | |
} | |
BEGIN { | |
"date +%z" | getline tz | |
close("date +%z") | |
- TZOFFSET = substr(tz, 1, 1) substr(tz, 2, 2)*3600 + substr(tz, 4, 2)*60 | |
+ TZ = substr(tz, 1, 1) substr(tz, 2, 2)*3600 + substr(tz, 4, 2)*60 | |
print("TZ" tz) | |