[Shell Script]在檔案中取代含有特殊符號的內容

  • 4863
  • 0

摘要:[Shell Script]在檔案中取代含有特殊符號的內容

其實這個方法在http://www.dotblogs.com.tw/shuinvy/archive/2014/11/20/147380.aspx 已經提過了,但是針對實例做一些補充。

後來發現,使用這個方法會比以往的字串搜尋、取代(sed -i "s/$oldword/$newword/g" "$File")來得更保險,幾乎是萬用,不用擔心escape問題。

誰也沒想到我搜尋了千千萬萬的文章,

只為了在字串取代中使用有&(ampersand)的變數竟然都無解!

試過了一次又一次的escape數量(\),在grep的時候就是行不通!

於是才想到用保險的方法。雖然比較麻煩,但是在處理檔案時會比較安心。

 

其實也是因為我以前的做法是這樣的:

oldword=$(cat "$file" | grep '$keyword')
sed -i 's|'$oldword'|'$newword'|g' "$file"
 
雖然只需要兩行,因為搜尋的字串包含&符號,就折騰了我半個小時......
 

關於保險的做法:

最重要的一點就是你要使用你搜尋到的"那一行"來做字串取代,

假如你是一行有很多需要取代,就可能要先取代一次再用同樣的方法取代另一個字,

關鍵就在於要搜尋到那一行。

要是連搜尋的那一行也有特殊字元,這方法可能就又不適用了......

就好比你已經知道你要取代的那一行固定在24行,或者那一行跟其他行絕對不同的字樣是"HURL="(那一行以HURL為開頭)抑或";For URL"(以;做註解的結尾,因此搜尋的字眼以;與固定註解來做)舉例,

步驟就是:

1.先找到舊的那一行

2.將需要替代的新字串插入到那一行,並且存到暫存檔案2

3.新的一行會插入到舊的一行的上面(比方原本舊的是第6行,則新的會在第6行,舊的變成第7行)

4.在暫存檔案2刪除舊的一行,舊的一行就是原本舊的一行的行數加一

5.刪除後的檔案放到暫存檔案1,並且刪除暫存檔案2

6.暫存檔案1就是我們要的結果,因此將暫存檔案1改名為我們原本的檔案名稱(同時也覆蓋原本檔案,暫存檔案1就沒了)

然而上次沒說到的就是,因為是新的檔案,雖然跟我們原本的檔名一樣,

檔案的權限可能不一樣,

因此還要再多加一個步驟:

7.用chmod改變檔案的權限

因此這次結果就是:


oldLine=$(grep -n $query $file | awk -F':' '{print $1}')
sed $oldLine"i$newKey" "$file" > "$file"".tmps2"
nextLine=`expr $oldLine + 1`
sed -e $nextLine'd' "$file"".tmps2" > "$file"".tmps"
rm "$file"".tmps2"
mv "$file"".tmps" "$file"
chmod 755 "$file"

 

因為每次取代都要寫這麼長串(7行的script語法),

乾脆把它放在function裡面使用,


function ReplaceSpecial()
{
        oldLine=$(grep -n $1 $3 | awk -F':' '{print $1}')  #前面的$1是$oldword,$3是檔案$file(絕對路徑)
        sed $oldLine"i$2" "$3" > "$3"".tmps2"
        nextLine=`expr $oldLine + 1`
        sed -e $nextLine'd' "$3"".tmps2" > "$3"".tmps"
        rm "$3"".tmps2"
        mv "$3"".tmps" "$3"
        chmod 755 "$3"                                     #依情況修改檔案權限
}

# function使用方法
#變數在function就是$1(第一個參數),$2(第二個參數),......
ReplaceSpecial "$oldword" "$newword" "$file"

這樣非不得已(假如真的無法找到舊的那一行或指定的那一行)就使用這個方法做檔案中的字串取代吧!