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
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 -n '/^## Screenshots/,/^##/p' infile | sed '$d'