2011-11-21 36 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