我有一个包含多个部分的文本文件,我想打印其中一个部分.
部分文件看起来像
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)
sed -n '/## Screenshots ##/,/##/p' readme.md
这将开始打印,## Screenshots ##
直到##
找到下一个.如果你不想要最后##
一场比赛,最简单的是
sed -n '/## Screenshots ##/,/##/p' readme.md |head -n-1
这可以通过以下方式更轻松,更通用地完成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 -n '/^## Screenshots/,/^##/p' infile | sed '$d'
Run Code Online (Sandbox Code Playgroud)