2013-07-31 42 views
2

我想通過git過濾器命令中的數組來循環訪問數組,這意味着在內部的「」,我似乎無法獲得正確的語法。我試圖在循環中的當前迭代中獲取數組的值,但變量保持爲空,並在運行sed命令時發生錯誤。如果可以的話請幫忙。請注意,我的腳本中的其他變量正常工作。在git過濾命令(即引號內)中使用bash數組

declare -a oldFSarray=(principiumI principiumII principiumIII principiumIV prollecture1 prollecture2 prollecture3 prollecture4 prollecture4b prollecture5 prollecture6 prollecture7 prollecture8 prollecture9 prollecture10 prollecture11 prollecture12 prollecture13 prollecture14 prollecture15 prollecture16 prollecture17 prollecture18 dthreelecture19 dthreeaonelecture20 dthreeaonelecture21 dthreeaonelecture22 dthreeaonelecture23 dthreeaonelecture24 dthreeatwolecture25 dthreeathreelecture26 dthreeafourlecture27 dthreeafivelecture28 dthreeafivelecture29 dthreeasixlecture30 dthreesixlecture30b dthreeasixlecture31 donelecture32 donelecture33 donelecture34 donelecture35 donelecture36 donelecture37 donelecture38 donelecture39 donelecture40 donelecture41 donelecture42 donelecture43 donelecture44 donelecture45 donelecture46 donelecture47 donelecture48 donelecture49 donelecture50 donelecture51 donelecture52 donelecture53 dTlecture54 dTlecture55 dTlecture56 dTlecture57 dTlecture58 dTlecture59 dTlecture60 dTlecture61 dTlecture62 dTlecture63 dTlecture64 dTlecture65 dTlecture66 dTlecture67 dTlecture68 dTlecture69 dTlecture70 dTlecture71 dTlecture72 dTlecture73 dTlecture74 dTlecture75 dTlecture76 dTlecture77 dClecture78 dClecture79 dClecture80 dClecture81 dClecture82 dClecture83 dClecture84 dClecture85 dClecture86 dClecture87 dClecture88 dClecture89 dClecture90 dClecture91 dClecture92 dLlecture93 dLlecture94 dLlecture95 dLlecture96 dLlecture97 dLlecture98 dLlecture99 dLlecture100 dLlecture101 dLlecture102 dLlecture103 dLlecture104 dLlecture105 dLlecture106 dLlecture107 dLlecture108 dLlecture109 dLlecture110 dLlecture111 dLlecture112 dLlecture113 dLlecture114 dLlecture115 dLlecture116 dLlecture117 dLlecture118 dLlecture119 dLlecture120 dLlecture121 dLlecture122 dLlecture123 dLlecture124 dLlecture125 dLlecture126 dLlecture127 dIlecture128 dIlecture129 dIlecture130 dIlecture131 dIlecture132) 
declare -a newFSarray=(principiumI principiumII principiumIII principiumIV Lectio_1 Lectio_2 Lectio_3 Lectio_4 Lectio_5 Lectio_6 Lectio_7 Lectio_8 Lectio_9 Lectio_10 Lectio_11 Lectio_12 Lectio_13 Lectio_14 Lectio_15 Lectio_16 Lectio_17 Lectio_18 Lectio_19 Lectio_20 Lectio_21 Lectio_22 Lectio_23 Lectio_24 Lectio_25 Lectio_26 Lectio_27 Lectio_28 Lectio_29 Lectio_30 Lectio_31 Lectio_32 Lectio_33 Lectio_34 Lectio_35 Lectio_36 Lectio_37 Lectio_38 Lectio_39 Lectio_40 Lectio_41 Lectio_42 Lectio_43 Lectio_44 Lectio_45 Lectio_46 Lectio_47 Lectio_48 Lectio_49 Lectio_50 Lectio_51 Lectio_52 Lectio_53 Lectio_54 Lectio_55 Lectio_56 Lectio_57 Lectio_58 Lectio_59 Lectio_60 Lectio_61 Lectio_62 Lectio_63 Lectio_64 Lectio_65 Lectio_66 Lectio_67 Lectio_68 Lectio_69 Lectio_70 Lectio_71 Lectio_72 Lectio_73 Lectio_74 Lectio_75 Lectio_76 Lectio_77 Lectio_78 Lectio_79 Lectio_80 Lectio_81 Lectio_82 Lectio_83 Lectio_84 Lectio_85 Lectio_86 Lectio_87 Lectio_88 Lectio_89 Lectio_90 Lectio_91 Lectio_92 Lectio_93 Lectio_94 Lectio_95 Lectio_96 Lectio_97 Lectio_98 Lectio_99 Lectio_100 Lectio_101 Lectio_102 Lectio_103 Lectio_104 Lectio_105 Lectio_106 Lectio_107 Lectio_108 Lectio_109 Lectio_110 Lectio_111 Lectio_112 Lectio_113 Lectio_114 Lectio_115 Lectio_116 Lectio_117 Lectio_118 Lectio_119 Lectio_120 Lectio_121 Lectio_122 Lectio_123 Lectio_124 Lectio_125 Lectio_126 Lectio_127 Lectio_128 Lectio_129 Lectio_130 Lectio_131 Lectio_132 Lectio_133 Lectio_134) 

function gitNameChangeFilter() 
{ 
oldfs=$1 
newfs=$2 
oldln=$3 
newln=$4 
basedirectory=$5 
mv $basedirectory/$oldfs $basedirectory/$newfs 
cd $basedirectory/$newfs 
    git filter-branch --tree-filter " 
     #test and then change edited text 
     if [ -e $oldfs.xml ] 
      then 
       mv $oldfs.xml $newfs.xml 
       for i in {0..137} 
        do 
         old=$oldFSarray[$i] //HERE IS THE PROBLEM 
         echo $old 
         new=$newFSarray[$i] //HERE TOO 
         echo $new 
         sed -i.bak 's/$old/$new/g' $newfs.xml //Error comes back that basically says $old is empty 
        done 

       sed -i.bak 's/Lectio $oldln/Lectio $newln/g' $newfs.xml 

      else 
       echo 'Nothing to do $oldfs does not exist' 
     fi 
} 

回答

2

在bash中,當您使用$var一個雙引號字符串("The value of var is $var")內,然後立即慶典擴展它。這會在您傳遞給git的參數中引用所有$variable時發生,因此,例如,當運行git命令時,​​將被替換爲oldFSarray$i th元素,其值爲$i

但是,它並不真正的問題是什麼old被設置在子shell,因爲下一行(echo $old)使用$old將立即與$old的當前值(如果有的話)來代替,因此部分其內容

old=$oldFSarray[$i] 
echo $old 

很可能將擴大到像這樣的腳本:

old=PrincipiumI[] 
echo 

(注意:你的腳本使用old=$oldFSarray[$i],這是不是對於s的語法對數組進行編碼。正確的語法是在上面的第一段,${oldFSarray[$i]}

我相信你所期望的是git會收到帶有變量引用的bash腳本,並執行它們。爲了使其工作,您需要用撇號(')包圍腳本,而不是雙引號。

但是,您還需要知道git將在子shell中執行腳本,並且子shell只能訪問導出的shell變量。從bash 4.2開始,至少,數組變量不能被導出。 (也就是說,你可以export他們,但它沒有效果。)所以你需要在你傳遞給git的腳本中創建數組。

這可能看起來很嚇人,但幸運的是declare -p以可以直接評估的格式輸出值。所以,你可以這樣做:

oldFSarray=(value1 value2 value3...) 
export make_oldFSarray="$(declare -p oldFSarray)" 
#... 
git filter-branch --treefilter=" 
    $make_oldFSarray 
    $make_newFSarray"' 
    # From here on down, $foo is not substituted 
    ' 
+0

我不太明白--treefilter雙引號=是=簽署型因爲git在使用等號時會給我一個錯誤 – Jeff

+0

@jeff:對不起,大多數實用程序在長選項後需要'='。我想git必須有所不同。 – rici

0

你錯過了這組索引數組名,併爲sed命令,你需要雙引號,以擴大在shell變量的括號。

    old=${oldFSarray[$i]} 
        new=${newFSarray[$i]} 
        sed -i.bak "s/$old/$new/g" $newfs.xml 
+0

由於子shell落成使用雙引號sed命令將過早colose子shell – Jeff