2016-01-24 26 views
0

在遍歷參數時,如何確定是否存在下一個參數?確定迭代遍歷參數時是否存在下一個參數

我試圖解決這個問題的方法是檢查下一個參數是否爲空,但遇到了一些問題。

在這個例子中,我打印當前參數的值,如果在此之後有參數,則打印一些消息。

我的方法:

使用$i+1其中$i+1會給你下一個索引值。

#!/bin/sh 

for i in "[email protected]" 
do 
    echo $i 
    if ! [ ${i+1}="" ]; then 
     echo "test" 
    fi 
done 

sh test 1 2 3 4 5 

但這並不奏效。我也嘗試過expr i + 1,但那不起作用。

如果有人可以給我一個關於如何解決這個問題的提示,這將是非常感激。

+0

你在困惑自己的危險到'1'等等直到'$ 5'等於'5'。你可能想用'sh test 2 4 6 8 10'作爲一個簡單的替代方案;它會告訴你'$ i'不是一個參數號。 –

+1

你需要知道'sh test abc''def''ghi'(它有5個參數給腳本,其中2和4是空字符串)會發生什麼。或者你是否想要確定在當前的論文之後是否存在另一個論點?默認情況下,shell將把'$ 6'的引用當作一個空字符串。一些shell有通過間接訪問變量的方法:在Bash中,可以使用:'x = 5; echo $ {!x}',並且在給定上面顯示的調用的情況下它會回顯'ghi'。所有的炮彈都有'eval',但是使用起來很危險。 OTOH,它在'all'shell中工作:'eval echo \ $$ x'也應該回顯'ghi'。 –

回答

3
#!/bin/sh 

while [ $# -gt 0 ] ; do 
    echo $1 
    if [ -n "${2+x}" ]; then 
    echo another arg follows 
    fi 
    shift 
done 
$ ./test.sh 1 2 3 
1 
another arg follows 
2 
another arg follows 
3 

這裏的竅門是,我們使用shift供消費的參數列表,而不是遍歷它。下一個參數總是爲$1,我們知道它存在,因爲我們只執行循環如果$#(位置參數的計數,不包括$0)是正數。要檢查是否有參數$2存在,我們可以使用${PARAM+WORD}擴展,如果PARAM不存在則不產生任何結果,否則產生WORD

當然,shift會破壞參數列表。如果你不想要這個,把東西變成一個函數。下面的例子顯示我們如何能夠兩次通過傳遞進入副本的功能,其中shift本地吃它處理相同的參數列表:具有`$ 1`等於

#!/bin/sh 

func() { 
    while [ $# -gt 0 ] ; do 
    echo $1 
    if [ -n "${2+x}" ]; then 
     echo another arg follows 
    fi 
    shift 
    done 
} 

func "[email protected]" 
func "[email protected]" 
 
$ ./test.sh 1 2 3 
1 
another arg follows 
2 
another arg follows 
3 
1 
another arg follows 
2 
another arg follows 
3 
+0

感謝Kaz的解釋:) – user3412839

+0

@ user3412839順便說一下,如果它算一些東西,我從來沒有見過一段shell代碼在數值上迭代位置參數。 (它在Awk程序中用於遍歷字段:for(i = 1; i <= NF; i ++){print $ i;}')。在shell中,「shift」是成語。 – Kaz

0

您可以使用一個計數器和檢查$#

n=1 

for i in "[email protected]"; do 
    echo "$i" 
    if [ $n -eq $# ]; then 
     echo "test" 
    fi 
    n=$(expr $n + 1) 
done 
+1

如果不打算使用'n = $(($ n + 1))'或其中一個變體,則可以使用'n = $(expr $ n + 1)'。 '$((...))'表示法是由shell的POSIX規範指定的。 –

+0

感謝@JonathanLeffler,我不知道'((..))'是否可用於舊的Bourne shell – anubhava

+1

這取決於Bourne shell的年齡。真正的Bourne貝殼,比如說1985年的老貝,並不支持它。你仍然可以在系統上找到類似的shell,例如'/ bin/sh'。Korn shell,Bash,Dash和其他現代shell通常遵循POSIX標準,通常帶有擴展名。如果'/ bin/sh'是其中一個鏈接的鏈接,則可以使用$((...))'符號。它有所不同。這個問題由於沒有標籤而變得複雜([tag:shell]和[tag:sh]是相當開放的)。 –