带有操作员的Shell命令后跟管道

带有操作员的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成功时,它应该像我发布的第一条命令一样工作。

+1

'ls ... | xargs grep'是毫无意义的(也是一个坏主意)。 grep可以一次接受多个文件。 – 2014-12-04 19:31:11

+0

对于每个要使用'grep'的文件,要么*重启行或者“不重启”? – 2014-12-04 19:32:15

+0

我正在做ls -rt,因为有多个文件。日志旋转,所以它会像server.log,server.log.1等。我想要的是最近的一个,这就是为什么我要在grep之前对日志进行排序,然后只打印最后一个匹配(不管哪个文件)。如果没有匹配的地方,我想打印'不重新启动'。 – Greg 2014-12-04 19:34:37

使用{到组的术语:

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' 

无需额外的壳层。

+0

运行一行命令不适用于我,它只是在下一行打印一个'>',就好像括号没有全部关闭一样。 – Greg 2014-12-04 20:11:29

+0

Gotcha - 忘记'''awk和尾巴后 - 固定!现在就试试。 – 2014-12-04 22:56:24

+0

太棒了 - 这很有道理。我喜欢这个也不需要subshel​​l。谢谢! – Greg 2014-12-05 23:40:03

可以将管内组命令通过使用括号:

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}" 

另外请注意,这是不安全的文件名与空间/等。