截断匹配字符串的最后一行直到 EOF 的 shell 命令输出
truncate shell command output from last line matching a string until EOF
我想截断 shell 脚本的输出,只打印匹配 string/regex 和 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 }'`
cnt2=`wc -l certbot.log | awk '{ print }'`
cnt3=$((cnt2-cnt1))
tail -n $cnt3 certbot.log
您可以为此使用 awk
:
awk '/^-{6}/{p=1; str=""; next} p{str = str [=10=] 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
我想截断 shell 脚本的输出,只打印匹配 string/regex 和 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 }'`
cnt2=`wc -l certbot.log | awk '{ print }'`
cnt3=$((cnt2-cnt1))
tail -n $cnt3 certbot.log
您可以为此使用 awk
:
awk '/^-{6}/{p=1; str=""; next} p{str = str [=10=] 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