我正在编写一个脚本,以从crontab中获取仅包含命令的列表。到目前为止,我的输入数据看起来像这样:
$ crontab -l | grep -i --color -v '^#' | awk '$0 ~ /^*/[0-9]{1,20}|*+/'
*/5 * * * * /usr/local/bin/bash msmtp-queue -r
*/5 * * * * /usr/bin/env bash /Users/tonybarganski/bin/offlineimap-fetch
*/15 * * * * /usr/bin/env bash ~/bin/checkMail
00 12 * * * /usr/local/bin/bash ~/bin/lbdb-fetchaddress-daily
* */3 * * * /usr/bin/env rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.log
结果打印'/usr/bin/env bash'或'/usr/local/bin/bash'或'* */3 * * *'之后的所有内容
msmtp-queue -r
offlineimap-fetch
checkMail
lbdb-fetchaddress-daily
rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.log
尝试我尝试从文件末尾($NF)开始打印直到第一个正斜杠的所有内容,但我只是在放置括号的地方出现语法错误:
$ crontab -l | grep -i --color -v '^#' |
awk -F'/' '{ if ($0 ~ /^*/[0-9]{1,20}|*+/) for(i=NF;i>0;i--) { if ( sub(///, "", $i) { print $i} } }'
awk: cmd. line:1: { if ($0 ~ /^*/[0-9]{1,20}|*+/) for(i=NF;i>0;i--) { if ( sub(///, "", $i) { print $i} } }
awk: cmd. line:1: ^ syntax error
如何做到这一点?
如果你想
打印'/usr/bin/env bash'或'/usr/local/bin/bash'或'* */3 * * *'
并给出示例的格式,您可以拆分不同的模式并检查是否至少有2部分。
如果file
包含样例数据:
awk '
{
n = split($0,a, /(^* */3 * * *|/usr/local/bin/bash|/usr/bin/env[[:space:]]+bash)[[:space:]]+/)
if (n > 1) {
print a[2]
}
}
' file
输出msmtp-queue -r
/Users/tonybarganski/bin/offlineimap-fetch
~/bin/checkMail
~/bin/lbdb-fetchaddress-daily
/usr/bin/env rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.log
从crontab中获取命令列表
我将丢弃5个第一个字段,让file.txt
内容为
*/5 * * * * /usr/local/bin/bash msmtp-queue -r
*/5 * * * * /usr/bin/env bash /Users/tonybarganski/bin/offlineimap-fetch
*/15 * * * * /usr/bin/env bash ~/bin/checkMail
00 12 * * * /usr/local/bin/bash ~/bin/lbdb-fetchaddress-daily
* */3 * * * /usr/bin/env rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.lo
然后
awk 'BEGIN{FS="[ ]"}{$1=$2=$3=$4=$5="";sub(/^ */,"");print}' file.txt
给输出
/usr/local/bin/bash msmtp-queue -r
/usr/bin/env bash /Users/tonybarganski/bin/offlineimap-fetch
/usr/bin/env bash ~/bin/checkMail
/usr/local/bin/bash ~/bin/lbdb-fetchaddress-daily
/usr/bin/env rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.lo
解释:我通知GNUAWK
字段分隔符(FS
)和输出字段分隔符(OFS
)是单空格。我没有使用默认的FS,因为它会导致将制表符更改为空格字符到空格并压缩空格(2个或多个连续空格变为单个空格)。对于每一行,我设置第1,第2,第3,第4和第5个字段为空字符串,然后使用sub
去除前导空格,然后使用print
更改行。
(在GNU Awk 5.0.1中测试)
如果你真的不希望在你的问题中输出,而是希望在当前接受的答案中显示输出,那么你只需要:
$ sed -E 's/([^ ]* ){5}//' file
/usr/local/bin/bash msmtp-queue -r
/usr/bin/env bash /Users/tonybarganski/bin/offlineimap-fetch
/usr/bin/env bash ~/bin/checkMail
/usr/local/bin/bash ~/bin/lbdb-fetchaddress-daily
/usr/bin/env rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.log
上面需要一个有-E
的sed来启用EREs,例如GNU或BSD sed。对于任何POSIX sed,您都可以使用sed 's/([^ ]* ){5}//' file
或使用任何POSIX awkawk '{sub(/([^ ]* ){5}/,"")}1' file
。
使用sed
(如适用)
$ sed s'/.*(bin/|/env )?bash |.** //' input_file
msmtp-queue -r
/Users/tonybarganski/bin/offlineimap-fetch
~/bin/checkMail
~/bin/lbdb-fetchaddress-daily
/usr/bin/env rsync -auv -f- index.lock --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.log
$ awk -F"bash|env bash|env" '!/^#/ {print $2}' <(crontab -l)
msmtp-queue -r
/Users/tonybarganski/bin/offlineimap-fetch
~/bin/checkMail
~/bin/lbdb-fetchaddress-daily
rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.log
如果你想考虑潜在的制表符:
mawk 'BEGIN { OFS=_;__=_="[^"(_=" \t]")"*["_; gsub("...",_,_); FS="^"(_)__ } NF=NF'
or
{n,g}awk 'BEGIN { OFS=_;FS="^("(_="[^"(_=" \t]")"*["_)"){5}" } NF=NF'
,
/usr/local/bin/bash msmtp-queue -r
/usr/bin/env bash /Users/tonybarganski/bin/offlineimap-fetch
/usr/bin/env bash ~/bin/checkMail
/usr/local/bin/bash ~/bin/lbdb-fetchaddress-daily
/usr/bin/env rsync -auv -f"- index.lock" --exclude={'Macintosh HD','MyArchive'} ~/mnt/ ~/.Backup/mnt/ > ~/crypto-vols-backup.log
如果不考虑制表符,则更简单:
{n,g}awk 'NF=NF' FS='^([^ ]+[ ]+){5}' OFS=