I would like to truncate the output of a shell script and only print the part between the last line matching a string/regex and EOF.
E.g when running letsencrypt certbot renew --post-hook "service apache2 reload; service nginx reload"
I get something like
... 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.
Now what I want to have is everything after the last -------
line, so the desired result would be
** 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.
I thought about some tail -n 15
command but I don’t want to adjust my script each time I add a new domain.
Thanks for your help!
Edit: In the meantime I found a solution on my own which is not as nice as @anubhava’s
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
Advertisement
Answer
You can use awk
for this:
awk '/^-{6}/{p=1; str=""; next} p{str = str $0 ORS} END{printf "%s", str}' file
This awk command matches ------
as starting text in any line and once it finds it we set a flag p
to 1
and initialize a buffer str
to empty. Next we keep adding each line into buffer str
if flag p
is set.
Note that if we encounter another ------
then we reinitialize str
to empty hence keeping lines from only last matched occurrence.
Output:
** 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.
Alternative solution is to use tac
before and after awk
and print only first match:
tac file | awk '/^-{6}/{exit} 1' | tac