我有:
bananaOPENqwertyCLOSErandomtextOPENgrapesCLOSEwhateverOPENsunshineCLOSEgreymoon
这一行可以包含更多的 OPEN 和 CLOSE 字符串。
我只想打印整行,只包含任何连续的 OPEN 和 CLOSE 之间的内容,并丢弃任何其他内容。即我想要这样的输出:
qwertygrapessunshine
我能想到的最接近的是:
sed -n 's/OPEN\(.*\)CLOSE/\1/g;p'
这显然行不通。
因为
sed
匹配是“贪婪的”(更准确地说,是最左边最长的),所以这很棘手。尝试:以上是在 GNU 上测试的
sed
。如果您使用的是 BSD/MacOS,则可能需要进行一些小但烦人的更改。这个怎么运作
请记住,默认情况下,sed 一次读入一行到它的模式空间中。这意味着,当我们开始处理模式空间时,它永远不会包含换行符。因此,我们可以使用换行符
\n
作为标记,不会产生歧义。s/OPEN/\n/g
替换
OPEN
为换行符默认情况下,
sed
一次只读入一行到它的模式空间。这意味着模式空间永远不会单独包含换行符。s/[^\n]*\n//
删除第一个
OPEN
(现在是换行符)之前的所有内容。请注意,
[\n]*
匹配零个或多个除换行符以外的任何内容。因此,[^\n]*\n
匹配零个或多个除换行符后跟换行符之外的任何内容。这意味着它匹配并包括下一个换行符。相比之下,因为 sed 表达式是“贪婪的”(最左边最长的),.*\n
所以匹配模式空间中直到并包括最后一个换行符的任何内容。s/CLOSE[^\n]*\n//g
删除从下一个换行符开始
CLOSE
到下一个换行符的所有内容。s/CLOSE.*$//
从最后一行删除
CLOSE
到行尾。