2017-09-11 3 views
1

Je voudrais tronquer la sortie d'un script shell et imprimer uniquement la partie entre la dernière ligne correspondant à une chaîne/regex et EOF.Sortie de la commande shell tronquée de la dernière ligne correspondant à une chaîne jusqu'à EOF

Par exemple, lors de l'exécution letsencrypt certbot renew --post-hook "service apache2 reload; service nginx reload" je reçois quelque chose comme

... 
http-01 challenge for domain1.tld 
Waiting for verification... 
Cleaning up challenges 

------------------------------------------------------------------------------- 
new certificate deployed without reload, fullchain is 
/etc/letsencrypt/live/domain1.tld/fullchain.pem 
------------------------------------------------------------------------------- 

------------------------------------------------------------------------------- 
Processing /etc/letsencrypt/renewal/domain2.tld 
------------------------------------------------------------------------------- 
Renewing an existing certificate 
Performing the following challenges: 
http-01 challenge for domain.tld 
http-01 challenge for www.domain2.tld 
Waiting for verification... 
Cleaning up challenges 

------------------------------------------------------------------------------- 
new certificate deployed without reload, fullchain is 
/etc/letsencrypt/live/domain2.tld/fullchain.pem 
------------------------------------------------------------------------------- 
** DRY RUN: simulating 'certbot renew' close to cert expiry 
**   (The test certificates below have not been saved.) 

Congratulations, all renewals succeeded. The following certs have been renewed: 
    /etc/letsencrypt/live/domain1.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain2.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain3.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain4.tld/fullchain.pem (success) 
** DRY RUN: simulating 'certbot renew' close to cert expiry 
**   (The test certificates above have not been saved.) 
Running post-hook command: service apache2 reload; service nginx reload 
Output from service: 
* Reloading web server apache2 
* 
* Reloading nginx configuration nginx 
    ...done. 

Maintenant, ce que je veux avoir tout est après la dernière ligne -------, de sorte que le résultat souhaité serait

** DRY RUN: simulating 'certbot renew' close to cert expiry 
**   (The test certificates below have not been saved.) 

Congratulations, all renewals succeeded. The following certs have been renewed: 
    /etc/letsencrypt/live/domain1.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain2.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain3.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain4.tld/fullchain.pem (success) 
** DRY RUN: simulating 'certbot renew' close to cert expiry 
**   (The test certificates above have not been saved.) 
Running post-hook command: service apache2 reload; service nginx reload 
Output from service: 
* Reloading web server apache2 
* 
* Reloading nginx configuration nginx 
    ...done. 

Je pensais à une commande tail -n 15 mais je ne veux pas ajuster mon script chaque fois que j'ajoute un nouveau domaine.

Merci pour votre aide!


Modifier: En attendant, je trouve une solution sur moi-même qui est pas aussi beau que @ anubhava de

cnt1=`grep -n "\----" certbot.log | tail -n1 | awk -F : '{ print $1 }'` 
cnt2=`wc -l certbot.log | awk '{ print $1 }'` 
cnt3=$((cnt2-cnt1)) 
tail -n $cnt3 certbot.log 

Répondre

1

Vous pouvez utiliser awk pour cela:

awk '/^-{6}/{p=1; str=""; next} p{str = str $0 ORS} END{printf "%s", str}' file 

Cette commande awk correspond ------ comme texte de départ dans n'importe quelle ligne et une fois qu'il l'a trouvé, nous avons mis un drapeau p à 1 et initialiser un tampon str pour vider. Ensuite, nous continuons à ajouter chaque ligne dans le tampon str si l'indicateur p est activé.

Notez que si nous rencontrons un autre ------, nous réinitialisons str pour le vider, ce qui permet de ne conserver les lignes que pour la dernière occurrence correspondante.

Sortie:

** DRY RUN: simulating 'certbot renew' close to cert expiry 
**   (The test certificates below have not been saved.) 

Congratulations, all renewals succeeded. The following certs have been renewed: 
    /etc/letsencrypt/live/domain1.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain2.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain3.tld/fullchain.pem (success) 
    /etc/letsencrypt/live/domain4.tld/fullchain.pem (success) 
** DRY RUN: simulating 'certbot renew' close to cert expiry 
**   (The test certificates above have not been saved.) 
Running post-hook command: service apache2 reload; service nginx reload 
Output from service: 
* Reloading web server apache2 
* 
* Reloading nginx configuration nginx 
    ...done. 

solution alternative est d'utiliser tac avant et après awk et imprimer uniquement le premier match:

tac file | awk '/^-{6}/{exit} 1' | tac 
+0

BTW votre solution fonctionne uniquement avec 'gawk 'pas avec' mawk' – simne7

+1

Je l'ai testé sur OSX qui est BSD awk et ça a bien marché là aussi. Peut être 'mawk' n'aime pas'/^ - {6}/', vous pouvez utiliser:'/------/'ici. – anubhava

+1

jep! C'est tout. Agréable. Je vous remercie :) – simne7