多亏了Ed Morton的回答,我可以使用Thunderbird和icalendar验证程序进行一些测试。我编辑了我的问题,添加了没有说明的条目以及具有精确要求的预期结果。
我正在编写一个脚本,以从平面文本文件生成icalendar文件。我想获取描述内容以及日期之后的行。说我有一个计划文件:
lun 06 05 2019 08 15 09 00 F206
A descritpion text.
ven 10 05 2019 11 00 11 45 G202
Another description text
- on multiple;
- lines.
lun 13 05 2019 08 15 09 00 F206
ven 17 05 2019 11 00 11 45 G202
A long description with more than 75 characters.
This happen often when multiple lines are
joined in one. So the program shoud split every lines
To 75 characters including the word description.
lun 20 05 2019 08 15 09 00 F206
A description text.
我的脚本看起来像这样,我是awk的新手:
#!/bin/bash
awk ' BEGIN { print "BEGIN:VCALENDAR\r\n\
... some entries here ...\r\n\
END:VTIMEZONE\r" ;}
$1~/^(lun|mar|mer|jeu|ven)$/ { print "BEGIN:VEVENT\r\n\
... some entries here ...\r\n\
DTSTART;TZID=Europe/Zurich:"$4""$3""$2"T"$5""$6"00\r\n\
DTEND;TZID=Europe/Zurich:"$4""$3""$2"T"$7""$8"00\r\n\
TRANSP:OPAQUE\r\n\
DESCRIPTION: >>>HERE I NEED THE DESCRIPTIVE LINES<<<< \r\n\
END:VEVENT\r"}
END { print "END:VCALENDAR" } ' < $1 > $1.ics
预期结果:
BEGIN:VCALENDAR
BEGIN:VEVENT
DTSTART;TZID=Europe/Zurich:20190506T081500
DTEND;TZID=Europe/Zurich:20190506T090000
DESCRIPTION:A descritpion text.
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Zurich:20190510T110000
DTEND;TZID=Europe/Zurich:20190510T114500
DESCRIPTION:Another description text\n- on multiple;\n- lines.
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Zurich:20190513T081500
DTEND;TZID=Europe/Zurich:20190513T090000
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Zurich:20190517T110000
DTEND;TZID=Europe/Zurich:20190517T114500
DESCRIPTION:A long description with more than 75 characters.\nThis happen
often when multiple lines are\njoined in one. So the program shoud split
every lines\nTo 75 characters including the word description.
END:VEVENT
BEGIN:VEVENT
DTSTART;TZID=Europe/Zurich:20190520T081500
DTEND;TZID=Europe/Zurich:20190520T090000
DESCRIPTION: A description text.
END:VEVENT
END:VCALENDAR
因此确切的要求是:
printf "%s%s", $0, "\\n"
答案 0 :(得分:1)
您确实在正确的轨道上。这是与flag
逻辑集成的脚本:
#!/bin/bash
awk 'BEGIN {print "BEGIN:VCALENDAR\r\n\
... some entries here ...\r\n\
END:VTIMEZONE\r" ;}
$1~/^(lun|mar|mer|jeu|ven)$/ && flag {flag = !flag; print "END:VEVENT\r"}
$1~/^(lun|mar|mer|jeu|ven)$/ && !flag {flag = !flag; print "BEGIN:VEVENT\r\n\
... some entries here ...\r\n\
DTSTART;TZID=Europe/Zurich:"$4""$3""$2"T"$5""$6"00\r\n\
DTEND;TZID=Europe/Zurich:"$4""$3""$2"T"$7""$8"00\r\n\
TRANSP:OPAQUE\r\n\
DESCRIPTION: "; next}
flag {print $0}
END { print "END:VCALENDAR" } ' < $1
输出:
BEGIN:VCALENDAR
... some entries here ...
END:VTIMEZONE
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190506T081500
DTEND;TZID=Europe/Zurich:20190506T090000
TRANSP:OPAQUE
DESCRIPTION:
Some descriptive lines here.
Lorem ipsumi dolor sit amet, consectetur adipiscing elitr.
END:VEVENT
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190510T110000
DTEND;TZID=Europe/Zurich:20190510T114500
TRANSP:OPAQUE
DESCRIPTION:
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
- enim
- ad minim veniam.
END:VEVENT
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190513T081500
DTEND;TZID=Europe/Zurich:20190513T090000
TRANSP:OPAQUE
DESCRIPTION:
exercitation ullamco
END:VEVENT
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190517T110000
DTEND;TZID=Europe/Zurich:20190517T114500
TRANSP:OPAQUE
DESCRIPTION:
quis nostrud
END:VCALENDAR
答案 1 :(得分:1)
$ cat tst.awk
BEGIN {
ORS="\r\n"
print "BEGIN:VCALENDAR"
print "... some entries here ..."
print "END:VTIMEZONE"
}
/^[^[:space:]]/ {
prtEndVevent()
print "BEGIN:VEVENT"
print "... some entries here ..."
date = $4 $3 $2
begt = $5 $6 "00"
endt = $7 $8 "00"
print "DTSTART;TZID=Europe/Zurich:" date "T" begt
print "DTEND;TZID=Europe/Zurich:" date "T" endt
next
}
{
gsub(/^[[:space:]]+|[[:space:]]+$/,"")
desc = (desc == "" ? "DESCRIPTION:" : desc RS) $0
}
END {
prtEndVevent()
print "END:VCALENDAR"
}
function prtEndVevent( wid) {
if ( desc != "" ) {
wid = 74
gsub(RS,"\\n",desc)
while ( desc !~ /^ ?$/ ) {
print substr(desc,1,wid)
desc = " " substr(desc,wid+1)
}
desc = ""
}
if ( endVevent != "" ) {
print endVevent
}
endVevent = "END:VEVENT"
}
。
$ awk -f tst.awk file
BEGIN:VCALENDAR
... some entries here ...
END:VTIMEZONE
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190506T081500
DTEND;TZID=Europe/Zurich:20190506T090000
DESCRIPTION:A descritpion text.
END:VEVENT
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190510T110000
DTEND;TZID=Europe/Zurich:20190510T114500
DESCRIPTION:Another description text\n- on multiple;\n- lines.
END:VEVENT
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190513T081500
DTEND;TZID=Europe/Zurich:20190513T090000
END:VEVENT
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190517T110000
DTEND;TZID=Europe/Zurich:20190517T114500
DESCRIPTION:A long description with more than 75 characters.\nThis happen
often when multiple lines are\njoined in one. So the program shoud split
every lines\nTo 75 characters including the word description.
END:VEVENT
BEGIN:VEVENT
... some entries here ...
DTSTART;TZID=Europe/Zurich:20190520T081500
DTEND;TZID=Europe/Zurich:20190520T090000
DESCRIPTION:A description text.
END:VEVENT
END:VCALENDAR
请注意,这是在字符位置而不是单词边界处换行,因此,如果单词越过第75个字符位置,则会被拆分。如果不希望这样,您可以更新prtDesc()
一次打印一个单词,检查所有单词+打印的空白加下一个单词的总长度是否小于75(并决定如何处理描述字符串是75个以上的字符,没有空格!),或调用UNIX命令fold
为您包装。
如果您正考虑使用getline
,请务必先阅读并完全理解http://awk.freeshell.org/AllAboutGetline。