使用sed在两个正则表达式之间打印行

Sud*_*dar 12 unix sed

我有一个包含多个部分的文本文件,我想打印其中一个部分.

部分文件看起来像

3. line 3
4. line 4

## Screenshots ##

1. line 1
2. line 2
3. line 3
4. line 4

## Changelog ##

3. line 3
4. line 4
Run Code Online (Sandbox Code Playgroud)

从这里我想要检索之间的所有行## Screenshots ##和下一部分的开始.下一节是## Changelog ##,但它可以是任何东西.因此,我们唯一可以依赖的是它将从一开始##.

另一个线程,我发现以下代码

sed -e "H;/${pattern}/h" -e '$g;$!d' $file
Run Code Online (Sandbox Code Playgroud)

我修改为

sed -e "H;/## Screenshots ##/h" -e '$g;$!d' readme.md
Run Code Online (Sandbox Code Playgroud)

现在,它检索从中开始的所有行## Screenshots ##,但它会打印所有行直到文件末尾.

然后我把它传递到另一个sed

sed -e "H;/## Screenshots ##/h" -e '$g;$!d' readme.md | sed "/^##/q" 
Run Code Online (Sandbox Code Playgroud)

但现在只打印

## Screenshots ##
Run Code Online (Sandbox Code Playgroud)

无论如何我可以在截图部分打印所有行吗?

Ken*_*ent 27

awk '/pattern/{p=1;print;next} p&&/^##/{p=0};p' file
Run Code Online (Sandbox Code Playgroud)

以"截图"为例:

kent$  awk '/^## Screenshot/{p=1;print;next} p&&/^##/{p=0};p' file
## Screenshots ##

1. line 1
2. line 2
3. line 3
4. line 4
Run Code Online (Sandbox Code Playgroud)

编辑添加说明

awk '/^## Screenshot/{p=1;print;next} : if match pattern, set p=1,print the line,read next line,(stop processing following scripts)
p&&/^##/{p=0}                         : if p==1 and match /##/ again (next section), set p=0
;p' file                              : if p==1, print the line
Run Code Online (Sandbox Code Playgroud)

只有sed

sed -n '/## Screensh/,/##/{/Scree/{p;n};/##/{q};p}' file
Run Code Online (Sandbox Code Playgroud)

EDIT2为sed cmd添加说明

-n                 -> not print
'/## Screen/, /##/ -> match range, I guess you knew it already
{                  -> if in this range
    /Scree/        -> and line matches /Screenshot/
        {p;n};     -> do print line, and read next row (skip doing rest processing)
    /##/           -> if line matches "##"
        q;         -> quit, we have done all printing
    p              -> if we come to here, print the line
}
Run Code Online (Sandbox Code Playgroud)


aba*_*asu 9

sed -n '/## Screenshots ##/,/##/p' readme.md

这将开始打印,## Screenshots ##直到##找到下一个.如果你不想要最后##一场比赛,最简单的是

sed -n '/## Screenshots ##/,/##/p' readme.md |head -n-1


Tho*_*hor 5

AWK

这可以通过以下方式更轻松,更通用地完成awk:

awk '/^##/ { p-- } /^## Screenshots/ { p=1 } p>0' infile
Run Code Online (Sandbox Code Playgroud)

如果你只想要一个部分,这将做:

awk '/^##/ { p=0 } /^## Screenshots/ { p=1 } p' infile
Run Code Online (Sandbox Code Playgroud)

输出:

## Screenshots ##

1. line 1
2. line 2
3. line 3
4. line 4
Run Code Online (Sandbox Code Playgroud)

说明

/^##/ { p-- }               # subtract one from the section counter
/^## Screenshots/ { p=1 }   # set section counter if current line has Screenshot 
p>0                         # print line if section counter greater than 0
Run Code Online (Sandbox Code Playgroud)

SED

sed -n '/^## Screenshots/,/^##/p' infile | sed '$d'
Run Code Online (Sandbox Code Playgroud)