如何使用sed在一行中的两个模式之间搜索多次出现的文本?

时间:2016-08-22 16:42:54

标签: linux bash sed

我有一个类似的文件:

“这是一个示例文件,用于在一行中查找p1 (第一个模式)和 p2(第二个模式)之间的文本,其中我们可以多次出现p1 后跟 p2,我只希望p1 p2之间的文字位于同一行。“< / p>

我想打印输出如下:   (第一个模式),然后是和

我尝试命令

cat filename | sed -e 's/.*p1\(.*\)p2.*/\1/g'

但它只打印出最后一个像:  

提前致谢

2 个答案:

答案 0 :(得分:2)

如果你有GNU .tooltip { -fx-background: rgba(255,255,205); -fx-text-fill: black; -fx-background-color: rgba(255,255,205,0.95); -fx-background-radius: 6px; -fx-background-insets: 0; -fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */ -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.5) , 10, 0.0 , 0 , 3 ); -fx-font-size: 0.90em; -fx-wrap-text: true; -fx-pref-width: 250; -fx-max-width: 250; } ,你可以使用perl兼容的正则表达式:

grep

说明:

  • grep -oP 'p1\K.+?(?=p2)' filename \K匹配后重置匹配。这样可以防止p1被包含在匹配结果中。
  • p1匹配一个或多个任意字符 - ungreedy ,仅表示最近出现的.+?
  • p2是一个先行断言。这意味着前一个模式(?=p2)需要跟.+?

答案 1 :(得分:0)

如果您没有GNU grep,您应该能够调整sed表达式来完成您的需要,例如:

sed 's/^.*p1\(..*\)p2.*$/\1/'

除了额外的'.'之外,它基本上是你所拥有的,它确保p1p2之间至少有1个字符可以通过反向引用输出。在这种情况下,每行中仅限{1} p1p2。全局替换的'g'将是多余的。

示例

如果p1codep2endcode111_000为有用文字,则可以执行以下操作:

$ printf "A line with a code111_000endcode and stuff\n" | 
sed 's/^.*code\(..*\)endcode.*$/\1/'
111_000

如果你有GNU grep,那就去那条路线,如果没有,就试一试。