带有操作员的Shell命令后跟管道
问题描述:
我想要一行命令从JBoss重新启动日志中获取最近的重新启动日期。我目前使用以下,其中工程带有操作员的Shell命令后跟管道
ls -rt $JBOSS_HOME/log/ser* |
xargs grep -ih "Incomplete\s*Deploy" |
awk '{print $1" "$2}' | tail -n 1
现在,我想如果grep的不匹配什么要补充的回声,即:
ls -rt $JBOSS_HOME/log/ser* |
xargs grep -ih "Incomplete\s*Deploy" ||
echo 'NO RESTART' |
awk '{print $1" "$2}' |
tail -n 1
这里的问题是,它似乎OR运算符现在会导致任何跟随失败的案例。如何指定我希望OR(回显)仅在grep失败时才被打印?当grep成功时,它应该像我发布的第一条命令一样工作。
答
使用{
到组的术语:
ls -rt $JBOSS_HOME/log/ser* |
xargs grep -ih "Incomplete\s*Deploy" && {
awk '{print $1" "$2}' |
tail -n 1
} ||
echo 'NO RESTART'
或作为一行:
ls -rt $JBOSS_HOME/log/ser* | xargs grep -ih "Incomplete\s*Deploy" && { awk '{print $1" "$2}' | tail -n 1; } || echo 'NO RESTART'
无需额外的壳层。
答
可以将管内组命令通过使用括号:
ls -rt $JBOSS_HOME/log/ser* | (xargs grep -ih "Incomplete\s*Deploy" || echo 'NO RESTART') | awk '{print $1" "$2}' | tail -n 1
这使得在子shell运行括号,它从管的观点来看,使得它们作为一个单一的命令工作的命令,即他们将输入并打印grep
匹配或'NO RESTART'
,然后将输入到awk
。
+0
谢谢 - 这就是我一直在寻找的 – Greg 2014-12-04 19:59:01
答
res=$(ls -rt $JBOSS_HOME/log/ser* | xargs grep -ih "Incomplete\s*Deploy" | awk '{print $1" "$2}' | tail -n 1)
echo "${res:-NO RESTART}"
另外请注意,这是不安全的文件名与空间/等。
'ls ... | xargs grep'是毫无意义的(也是一个坏主意)。 grep可以一次接受多个文件。 – 2014-12-04 19:31:11
对于每个要使用'grep'的文件,要么*重启行或者“不重启”? – 2014-12-04 19:32:15
我正在做ls -rt,因为有多个文件。日志旋转,所以它会像server.log,server.log.1等。我想要的是最近的一个,这就是为什么我要在grep之前对日志进行排序,然后只打印最后一个匹配(不管哪个文件)。如果没有匹配的地方,我想打印'不重新启动'。 – Greg 2014-12-04 19:34:37