我有多个 ICS 文件,其中包含以下内容:
...
PRIORITY:4
DESCRIPTION:this
was
a
triumph
COMPLETED:20180101T160000
...
我有兴趣解决DESCRIPTION
关键问题。密钥DESCRIPTION
可以出现在 ICS 文件中的任何位置。它并不总是跟着 key COMPLETED
。
使用ed
,我会这样做:
/DESCRIPTION/;/^[^ ]/-1p
这导致:
DESCRIPTION:this
was
a
triumph
但是,sed
似乎没有这种能力:
sed -n '/DESCRIPTION/,/^[^ ]/-1p' filename
结果是
sed:-e 表达式 #1,字符 22:未知命令:`-'
有没有办法做我想做的事sed
?
解决这个特殊问题
这个问题可以通过以下方式解决:
sed -n '/DESCRIPTION:/,/^\S/ { /\(DESCRIPTION\|^\s\)/p }' example.ics
但这感觉非常笨拙和冗长。
awk
似乎也不支持/begpat/,/endpat/-1
,所以你最终会得到类似的东西:
BEGIN { endpat = "^(DESCRIPTION|\\s)" }
/^DESCRIPTION/, $0 !~ endpat {
if ($0 ~ endpat) {print}
}
你非常接近:
会做你想做的。为什么?
/start/,/stop/!d
//d
会这样做(空模式//
匹配最后一个模式,因此该/stop/
行)p
在之前对其进行 rint,然后您会得到我确实显示的命令(再次使用空模式)用不同的方法更新
在您的评论中,您将其称为“解决方法”,从某种角度来看。实际上,对于我自己,我会选择一种不同的、更
sed
古怪的方法:这对恋人来说应该是自然的
sed
,但对某些人来说可能第一眼就觉得奇怪。它遵循“希望我能记住”的方法。那是什么?每次你来到没有缩进的一行时,你会想“我希望我能记住之前的行,它们是否值得打印”。然后我们简单地假设我们将它们放在我们的内存中,即保持空间,所以我们可以简单地x
改变模式空间和保持空间,d
如果它不以DESCRIPTION
它开头(如果它以它开头,它将默认打印)。好处
x
是,每条没有缩进的行都会自动在保持空间中,所以我们只需要将缩进的行添加到保持空间中H
。该/^ /{H;d;}
部分的作用(即d
避免对这些行进行输出或进一步处理)。现在,程序员会做相反的事情。他们可能会做这样的循环:
也就是说,删除所有内容,直到遇到
DESCRIPTION
关键字,然后开始一个循环以收集带有的行N
并循环直到有一行带有非空格\n[^ ].*
。在这种情况下,删除最后一行(再次利用空模式)。这也有效,但这不是
sed
.是的,sed 支持这样的地址范围:
在您的情况下,尝试使用
-E
扩展正则表达式的选项。