Imprimer des lignes entre deux regex en utilisant sed

J’ai un fichier texte qui contient plusieurs sections et je veux imprimer une de ces sections.

Une partie du fichier ressemble à

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 

De cela, je veux récupérer toutes les lignes entre les ## Screenshots ## et le début de la section suivante. Ici, la section suivante est ## Changelog ## , mais cela pourrait être n’importe quoi. Donc, la seule chose sur laquelle nous pouvons compter, c’est qu’elle commence par ## .

D’ un autre sujet , j’ai trouvé le code suivant

 sed -e "H;/${pattern}/h" -e '$g;$!d' $file 

que j’ai modifié pour

 sed -e "H;/## Screenshots ##/h" -e '$g;$!d' readme.md 

Maintenant, il récupère toutes les lignes à partir de ## Screenshots ## , mais il imprime toutes les lignes jusqu’à la fin du fichier.

Je l’ai ensuite canalisé à un autre sed comme

 sed -e "H;/## Screenshots ##/h" -e '$g;$!d' readme.md | sed "/^##/q" 

Mais maintenant, il imprime seulement

 ## Screenshots ## 

Y at-il de toute façon je peux imprimer toutes les lignes dans la section des captures d’écran?

 awk '/pattern/{p=1;print;next} p&&/^##/{p=0};p' file 

prendre la “Screenshot” comme exemple:

 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 

EDIT append une explication

 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 

sed seulement

 sed -n '/## Screensh/,/##/{/Scree/{p;n};/##/{q};p}' file 

EDIT2 ajoute une explication à 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 } 

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

Cela va commencer à imprimer à partir de ## Screenshots ## jusqu’à ce que le prochain ## soit trouvé. Si vous ne voulez pas le dernier match ## , le plus simple est

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

awk

Cela peut être fait plus facilement et de manière plus générique avec awk :

 awk '/^##/ { p-- } /^## Screenshots/ { p=1 } p>0' infile 

Si vous ne voulez qu’une seule section, cela fera:

 awk '/^##/ { p=0 } /^## Screenshots/ { p=1 } p' infile 

Sortie:

 ## Screenshots ## 1. line 1 2. line 2 3. line 3 4. line 4 

Explication

 /^##/ { 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 

sed

 sed -n '/^## Screenshots/,/^##/p' infile | sed '$d'