2014-02-23 25 views
0
for m in $count 
    do 
     `cat $op ${arr[$m]} > $op1` 
     `rm -f $op` 
     `touch $op` 
     `cat $op1 ${arr[$m+1]} > $op` 
     if [ $m ge $count ]; then 
     `rm -f $op1` 
     `touch $op1` 
     fi 
     m=$((m+1)) 
    done 

我想從開始計數2連續循環到結束計數10。 $ count = 10這裏。但是上面這段代碼只執行一次for循環。在shell腳本中連續循環使用

+3

你的腳本中是否真的有很多反引號,或者試圖讓代碼看起來像代碼?要獲取代碼,請按照您希望看到的方式編寫代碼,然後選擇它,然後使用編輯框上方的**按鈕 - 但您已經足夠長時間了,應該知道這一點。所寫的代碼將會'工作',但僅僅是因爲Unix命令對成功保持沉默並且所有命令都不會產生標準輸出,所以反引號執行一個空命令,但這是寫shell的一種簡單的反常方式。 –

回答

4

下雨的星期天 - 有多少空閒時間 - 長的答案;)

許多國際空間站你的腳本,一些推薦的解決方案。因爲您使用的是建築m=$((m+1)) - 將使用bash作爲「外殼」。 (考慮加入bash標籤)

對於週期 - 幾種可能性

count=10 
m=2       #start with 2 
while (($m <= $count))  #while m is less or equal to 10 
do       #do 
     echo $m    #this action 
     let m++    #increment m (add one to m) 
done       #end of while 

或者,如果算上是一個常數(不變量),你可以寫

for m in {2..10} #REMEMBER, will not works with a variables, like {2..$count} 
do 
    echo "$m" 
done 

另一種變體 - 使用seqman seq)指令進行計數

for m in $(seq 2 ${count:=10}) # ${count:=10} - defaults the $count to 10 if it is undefined 
do 
    echo $m 
done 

或類C爲環路

let count=10 
for ((m=2; m<=count; m++)) 
do 
     echo $m 
done 

所有4個循環產生:

2 
3 
4 
5 
6 
7 
8 
9 
10 

所以,現在具有正確的週期。現在添加您的具體操作。

的:

rm -f $op 
touch $op 

可以由一個命令

echo -n > $op #echo nothing and write the "nothing" into the file 

它更快被替換,因爲echobash builtin(不啓動兩個外部命令)

所以你的行爲可能看起來像

cat $op ${arr[$m]} > $op1 
echo -n > $op 
cat $op1 ${arr[$m+1]} > $op 

在這種情況下,echo是無用的,這是因爲第二cat將反正寫入其輸出 到$ OP(和之前寫入縮短了文件大小爲零),所以該結果是 與上述

相同
cat $op ${arr[$m]} > $op1 
cat $op1 ${arr[$m+1]} > $op  

這兩個cat命令可以短到一個,使用bash的>>追加到文件重定向

cat ${arr[$m]} ${arr[m+1]} >> $op 

整個腳本可以看樣下

#making a testing environment 

for f in $(seq 12)    #create 12 files opdata-N 
do 
    arr[$f]="opdata-$f"   #store the filenames in the array "arr" 
    echo "data-$f" > ${arr[$f]} #each file contains one line "data-N" 
done 
#echo ${arr[@]} 

#setting the $op and $op1 filenames 
#consider choosing more descriptive variable names 
op="file_op" 
#op1="file_op1" #not needed 

#add some initial (old) value to $op 
echo "initial value" > $op 
#end of creating the testing environment 

#the script 
count=10 
for m in $(seq 2 $count) 
do 
    cat ${arr[$m]} ${arr[m+1]} >> $op 
done 

末,文件$op將包含:

initial value 
data-2 
data-3 
data-3 
data-4 
data-4 
data-5 
data-5 
data-6 
data-6 
data-7 
data-7 
data-8 
data-8 
data-9 
data-9 
data-10 
data-10 
data-11 

順便說一句,你確定的結果呢?因爲如果只是想添加file-2 ... file-10$op結束(不重複的條目),你可以簡單的寫:

cat file-{2..10} >> $op #the '>>' adds to the end of file... 

或使用你的數組:

startpos=2 
count=10 
cat ${arr[@]:$startpos:$count} >> $op 

UFFF ..;)

ps:通常情況下,將變量用雙引號括起來是一種很好的做法,如"$filename" - 在上述示例中,爲了提高可讀性,我省略了它們。

+0

非常有用的答案。如果可以的話,我會加倍努力。生產性地使用星期天! – Floris

+0

非常有用的一個。謝謝:-) – Angus

+0

很好地完成; 'echo -n> $ op'的一個更短的,也是更可移植的替代方法是使用':'builtin':> $ op'。 – mklement0

0

改爲使用while循環。

for循環是當您有多個對象進行迭代時。你只有一個,即$ count。

1

任何循環都需要一個「保持循環的條件」。當您使用

for m in count 

類型的循環,條件是「如果有收集count更多的元素,選擇下一個和繼續下去」。這似乎不是你想要的。您正在尋找bash相當於

for(m = 0; m < 10; m++) 

我想。要做到這一點,最好的方法是 - 用正是那種循環的(但要注意 - 一對額外的圓括號和分號):

#!/bin/bash 
# Display message 5 times 
for ((i = 0 ; i < 5 ; i++)); do 
    echo "Welcome $i times." 
done 

see nix craft for original

我想你可以將此擴展到您的情況...如果我理解正確你的問題,你需要這樣的事:

for ((m = 2; m <= 10; m++)) 
    do 
    cat $op ${arr[$m]} > $op1 
    rm -f $op 
    touch $op 
    cat $op1 ${arr[$m+1]} > $op 
    if [ $m ge $count ]; then 
     rm -f $op1 
     touch $op1 
    fi 
    done 
+0

這很好。感謝您解釋 – Angus