在 Bash 上下文中我想提取所有文字出现在不同行但不构成整行的两个模式之间。因此,我特别想在模式出现的行上打印文本,但在开始模式之后开始,在停止模式之前结束。
- 例如,如果输入如下所示:
This is line 1 Something else Line 3
- 和模式是
This
和3
- 那么期望的输出是:
is line 1 Something else Line
答案1
使用 GNU grep
、Lookbehind(?<=This )
和 Lookahead (?= 3)
:
grep -Poz '(?<=This )(.|\n)*(?= 3)' file
输出:
是1号线 其他的东西 线
参见:man grep
和Stack 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
这具有相同的效果,但表述不同。它会删除输入中不属于我们想要的部分的部分,并在输出之前修剪我们想要的每个部分的起始行和结束行。