如何提取两个模式之间的所有文本(包括模式出现的行上的文本)?

如何提取两个模式之间的所有文本(包括模式出现的行上的文本)?

在 Bash 上下文中我想提取所有文字出现在不同行但不构成整行的两个模式之间。因此,我特别想在模式出现的行上打印文本,但在开始模式之后开始,在停止模式之前结束。

  • 例如,如果输入如下所示:
    This is line 1
    Something else
    Line 3
    
  • 和模式是This3
  • 那么期望的输出是:
    is line 1
    Something else
    Line
    

答案1

使用 GNU grep、Lookbehind(?<=This )和 Lookahead (?= 3)

grep -Poz '(?<=This )(.|\n)*(?= 3)' file

输出:

是1号线
其他的东西
线

参见:man grepStack Overflow 正则表达式常见问题解答

答案2

Perl 来拯救:

perl -0777 -ne 'BEGIN { ($f, $t) = (shift, shift) }
                /$f\s*(.*)\s*$t/s and print $1
               ' This 3 input.txt
  • -0777打开“slurp模式”,即将整个文件读入内存并进行处理;
  • -n通过代码处理输入;
  • 一开始,前两个参数存储在变量$f和$t中;
  • 如果输入包含两个模式之间的任何内容,它将存储在 $1 中并打印。

答案3

扩展正则表达式模式下的 GNU sed

sed -E '
  /This/,/3/ s/(^|\s+)(This|3)(\s+|$)//
' file

假设搜索词This 不会出现在其他文本中。

答案4

sed

$ cat file
This is line 1
This is Something else
Line 3
Line 33
This is more
data here
The 3rd bumblebee was never seen
$ sed -n '/.*This /,/ 3.*/ { s///; p; }' file
is line 1
This is Something else
Line
is more
data here
The

编辑sed脚本输出输入文件的部分。每个部分都以与开始模式匹配的行开始.*This,并以与结束模式匹配的行结束3.*。该脚本还会从起始行中删除与起始模式匹配的子字符串,并从结束行中删除与结束模式匹配的子字符串。

或者,

$ sed -e '/.*This /,/ 3.*/!d' -e 's///' file
is line 1
This is Something else
Line
is more
data here
The

这具有相同的效果,但表述不同。它会删除输入中不属于我们想要的部分的部分,并在输出之前修剪我们想要的每个部分的起始行和结束行。

相关内容