linux - 截断匹配字符串的最后一行直到 EOF 的 shell 命令输出

标签 linux shell awk tail

我想截断 shell 脚本的输出,只打印匹配字符串/正则表达式和 EOF 的最后一行之间的部分。

例如,当运行 letsencrypt certbot renew --post-hook "service apache2 reload; service nginx reload" 我得到类似的东西

...
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.

现在我想要的是最后 -------- 行之后的所有内容,因此所需的结果将是

** 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.

我考虑过一些 tail -n 15 命令,但我不想在每次添加新域时都调整我的脚本。

感谢您的帮助!


编辑:与此同时,我自己找到了一个不如@anubhava 的解决方案好

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

最佳答案

您可以为此使用 awk:

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

这个 awk 命令匹配 ------ 作为任何行的起始文本,一旦找到它,我们将标志 p 设置为 1 并将缓冲区 str 初始化为空。接下来,如果设置了标志 p,我们继续将每一行添加到缓冲区 str 中。

请注意,如果我们遇到另一个 ------,那么我们会将 str 重新初始化为空,从而仅保留最后一次匹配的行。

输出:

** 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.

替代方案是在awk前后使用tac,只打印第一个匹配项:

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

关于linux - 截断匹配字符串的最后一行直到 EOF 的 shell 命令输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46158985/

相关文章:

unix - 每行打印一个字

linux - 基于linux系统的一栏文字电影加一些文字?

linux - 制作一个 "copy"的linux系统

linux - ' : not a valid identifier Read and Curl

linux - 《Linux 内核模块程序员指南》中 chardev.c 示例的问题

linux - 无法使用 sudo -u username mkdir/var/log/test 创建目录

python - 当有 UTF-8 字符时,如何将输出定向到文件?

python - 在ubuntu中打开spyder

python - 在python中解析一个特殊的xml

linux - gawk 不会过滤掉更大的数字吗?