sed regexp - 匹配输出中额外不需要的行

sed regexp - extra unwanted line in matching output

我有这个文件

~/ % cat t
---
    abc
def DEF    
ghi GHI
---
123
456

我想提取三个破折号之间的内容,所以我尝试

sed -En '{N; /^---\s{5}\w+/,/^---/p}' t

即3 个短划线后跟 5 个空格(包括换行符),后跟一个或多个单词字符并以另一组三个短划线结尾。这给了我这个输出

~/ % sed -En '{N; /^---\s{5}\w+/,/^---/p}' t
--- 
    abc
def DEF
ghi GHI
---
123

我不想要带有“123”的那一行。我为什么会这样?我该如何调整我的表情来摆脱它? [编辑]:重要的是前三个破折号后的四个缩进空格在表达式中匹配。

这里不需要使用模式 space - 范围模式就可以了。

$ sed -n '/^---/,/^---/p' t 
---
    abc
def DEF    
ghi GHI
---

在 GNU sed 4.7 和 OSX sed 中测试。

我相信你可以使用

perl -0777 -ne '/^---\R(\s{4}\w.*?^---)/gsm && print "\n";' t

详情:

  • -0777 - 将文件压缩成单个变量
  • ^---\R(\s{4}\w.*?^---) - 行首 (^),---,一个换行符,然后是第 1 组:四个空格,一个字符字符,然后是零个或多个字符尽可能少,然后在行首 ---
  • gsm - global,返回所有匹配项,s 表示 . 匹配任何字符,包括换行字符,因为 m 表示 ^ 现在匹配任何行的开头,而不仅仅是字符串开头
  • && print "\n" - 如果匹配,打印第 1 组值 + 换行符。

这可能适合您 (GNU sed):

sed -En '/^---/{:a;N;/^ {4}\S/M!D;/\n---/!ba;p}' file

打开扩展正则表达式 (-E) 并关闭隐式打印 (-n)。

如果一行开始 --- 并且下一行缩进 4 个空格,则收集以下行直到另一个行开始 --- 并打印它们。

如果下一行不符合上述条件,删除第一行并重复。

所有其他行将不打印而通过。

N.B。第二个正则表达式上的 M 标志用于多行匹配,因为第一行已经开始 --- 下一行必须缩进。