2014-04-25 38 views
1

我正在bash中創建一個程序,它使用我創建的數字創建了一個histoplot。這些數字是這樣存儲的(其中第一個數字是文件的一行上有多少個單詞,第二個數字是給定文件中某一行上該單詞的數量出現的次數。)Bash for loop參數意外行爲

1 1 
2 4 
3 1 
4 2 

這應該產生:

1 # 
2 #### 
3 # 
4 ## 

,但我得到的輸出是:

1 # 
2 # 
3 # 
4 # 

但是for循環是不承認我的變量 「hashNo」 是一個數字。

#!/bin/bash 
if [ -e $f ] ; then 
     while read line  
    do  
     lineAmnt=${line% *} 
     hashNo=${line##* } 
     #VVVV Problem is this line here VVVV 
      for i in {1..$hashNo} 
      #This line ^^^^^^^ the {1..$hashNo} 
      do 
      hashes+="#"  
      done 
     printf "%4s" $lineAmnt 
     printf " $hashes\n" 
     hashes="" 
    done < $1 
fi 

,如果我與一些替代hashNo代碼工作(例如:4,使4個哈希在我的輸出),但它需要能夠與各行改變(在文件中沒有的所有行都會有相同的金額在這些字符

感謝您的幫助:d

+0

重複許多許多問題。 –

回答

1

bash序列表達式必須從整數或字符來形成,沒有參數替換前手發生。這是因爲,按所述bash DOCO:

擴展的順序是:括號擴展,波浪線擴展,參數,變量和算術擴展和命令替換,字分裂(在左到右的方式進行)和路徑名稱擴展。

換句話說,括號擴展(包括序列表達形式)首先發生

在任何情況下,這呼喊要做作爲一個函數,以便它可以容易地從任何地方進行,並且也取得了更有效的:

#!/bin/bash 

hashes() { 
    sz=$1 
    while [[ $sz -ge 10 ]]; do 
     printf "##########" 
     ((sz -= 10)) 
    done 
    while [[ $sz -gt 0 ]]; do 
     printf "#" 
     ((sz--)) 
    done 
} 

echo 1 "$(hashes 1)" 
echo 2 "$(hashes 4)" 
echo 3 "$(hashes 1)" 
echo 4 "$(hashes 2)" 

其輸出,如所期望:

1 # 
2 #### 
3 # 
4 ## 

使用第一個循環(一次執行十次散列)幾乎肯定會比一次添加一個字符更有效率,並且如果您願意,您可以在此之前執行大小爲50的循環,以獲得更多如果您的價值可能更大,則可以提高效率

+0

謝謝,非常翔實 –

1

你的循環應該是

for ((i=0; i<hashNo; i++)) 
do 
     hashes+="#"  
done 

您也可以通過使用eval和COM與堅持循環普通話取代$()

for i in $(eval echo {1..$hashNo}) 
do 
    hashes+="#"  
done 
+0

我不知道你可以在bash中做C++風格的循環:O –

+0

它在bash中是完全有效的c風格循環,你可以在這裏看到很多'for..loop'的方法http://www.thegeekstuff。com/2011/07/bash-for-loop-examples/ –

+0

感謝您的幫助:) –

1

我嘗試這樣for ((i=1; i<=$hashNo; i++))爲for循環中,它似乎是工作

+0

工作很好!謝謝 –