1. 程式人生 > >shell指令碼的字串匹配

shell指令碼的字串匹配

今天遇到了這樣的一個問題:
    在一個有幾百行的模板檔案中,我想找出具有vendor=xxxxx&&yyyyyy模式的行並把這個xxxxx替換成大寫

那麼為了方便說明問題,我舉個例子,比如我有檔案test,內容為:

aa=aavalue&&bb=bbvalue
aa=aa2value&&bb=bb2value
aa=aa3value&&bb=bb3value
cc=mmmmmmm&&dd=nnnnnnnnn
ee=ssssssss&&ffttttttttt

我現在希望把aa=xxxxxx&&bb=yyyyy中的xxxxxx截取出來,然後轉換成大寫,最後在指令碼中進行相應的查詢替換。

方案一:
  利用grep和shell中的變數替換
  egrep -n "^aa" test.txt|while read line;do str2=${line%%&*};str3=${str2##*aa=};echo $str3|tr a-z A-Z;done;

返回結果:
AAVALUE
AA2VALUE
AA3VALUE

再次查詢並執行替換命令略。。。。
 
 注意,這裡的關鍵部分就是${line%%&*}這一塊,它的意思是"從每行的結尾開始匹配,找每行的最後一個&,然後返回剩餘部分"。
 說明一下,變數的擴充套件匹配一共有6種,由於後兩種沒有用到,這裡僅提供4種,分別是:
 
1> ${variable#pattern}
如果pattern匹配variable的開始部分,從variable的開始處刪除字元直到第一個匹配的位置,包括匹配部分,返回剩餘部分。

2> ${variable##pattern}
如果pattern匹配variable的開始部分,從variable的開始處刪除字元直到最後一個匹配的位置,包括匹配部分,返回剩餘部分。

3> ${variable%pattern}
如果pattern匹配variable的結尾部分,從variable的結尾處刪除字元直到第一個匹配的位置,包括匹配部分,返回剩餘部分。

4> ${variable%%pattern}
如果pattern匹配variable的結尾部分,從variable的結尾處刪除字元直到最後一個匹配的位置,包括匹配部分,返回剩餘部分。

如果我把匹配模式變成${line%&*},即:
egrep -n "^aa" test|while read line;do str2=${line%&*};echo $str2|tr [a-z] [A-Z];done;
則,結果變為:
1:aa=aavalue&
2:aa=aa2value&
3:aa=aa3value&
這就類似於正則表示式中的惰性模式和貪心模式。

那麼如果我希望匹配bb=yyyyy中的yyyyyy,則需要用到${line#&*}或${line##&*}了。

方案二:

利用awk和sed
sed -n 's/aa=\(.\+\)&&.*/\1/p' test.txt|awk '{print toupper($1);}';
結果輸出:
AAVALUE
AA2VALUE
AA3VALUE
再次進行查詢替換方式,略。。。

終極方法:

   原來sed 裡有個\U表示大小寫轉換的匹配關係

   sed -n 's/aa=\(.\+\)&&.*/\U\1/p' test.txt