2011-11-21 37 views
1

我在bash中有一个for循环;Bash“for”循环,如果条件计数为零?

for Names in `grep "name" $people` 
do 
    echo "name is $name" 
done 

我怎样才能有一个if语句,说类似的东西;

for Name in `grep "name" $people` 
# Make sure we found some names 
if [ "count of $Name=0" ] 
then 
    echo "no names found" 
fi 

# Else, if we did grep out a list of names, print them 
do 
    echo "name is $Name" 
done 

回答

1

执行grep第一和它的结果存储在变量中。然后检查是否返回了一些内容,例如wc。如果是这样,用grep的结果运行循环。

+0

这似乎是最简单,最直接的病房解决方案。谢谢你:D – jwbensley

+0

在bash中,KISS原则比任何其他语言都要好得多(除了perl当然...) – mouviciel

1

你不能在循环内部做到这一点。在循环内将标志设置为true,或者检查参数的数量。

set -- `grep "$name" people` 
case $# in 0) echo no names found >&2;; 
    *) for Name; do # special form - loop over $* 
     echo name is "$Name" 
    done ;; 
esac 
+0

我喜欢这个方法tripleee,使用case语句留下良好的空间来添加额外的检查,我可以执行而不是只是“有数据”,“没有数据”。尽管我接受的答案是最简单直接的答案,但我想我会在另一个稍微复杂的脚本中尝试一下,谢谢! – jwbensley

4

添加compound conditional test (&&)打印的调试文本如果for块有返回代码0(这意味着它从来没有进入循环,并呼吁false):

for NAME in $(grep "name" $people) 
do 
    echo "Name is ${NAME}" 
    false 
done && echo "no names found" 

如果你不这样做喜欢读的方式,只是颠倒了:

! for NAME in $(grep "name" $people) 
do 
    echo "Name is ${NAME}" 
    false 
done || echo "no names found" 
+0

逻辑有点倒退。我想可以在某个地方用战术否定来理清。 – tripleee

+0

我非常喜欢这种方法,谢谢。它教会了我一种研究这个问题的逻辑的新方法,但正如tripleee所说的那样,稍微向后一点,我希望其他人能够轻松地阅读我的脚本。 – jwbensley

+0

更新为(也许?)使它看起来更正确。 –

1

这可能为你工作:

sed -n '/name/{h;s//name is &/p};${x;/./!s/^/no names found/p}' $people 

这假设$people至少是一条线

编辑的文件:说明 - -n防止默认打印输出到标准输出。在文件$people的每一行中搜索name,并且如果找到复制行来保存空间(HS)并且预先将name is设置为值并打印输出。在最后一行交换到HS,如果它不包含任何打印输出no names found

一个bash替代方案是:

names=($(grep "name" $people)) 
((${#names[@]})) && printf "name is %s\n" "${names[@]}" || printf "no names found\n" 

编辑:填充阵列namesgrep输出。测试数组names的大小,如果它不为零,则将每个值加上name is并打印出其他打印输出no names found

+0

谢谢potong。我是一个全新的sed newb,所以我无法阅读你提供的例子并且100%理解它。然而,阅读你bash的替代品我印象非常深刻,那真是太棒了!这给了我一个关于情况和Bash逻辑的新观点,非常感谢:D – jwbensley