2012-11-21 56 views
1

我希望能夠確保配置文件的一行包含附加路徑。使用sed重寫文件行

文件中的行看起來是這樣的:

checkedpaths=${myapp.base}/lib 

如果沒有$ {} myapp.base/bin中就行了,我想行追加到類似:

checkedpaths=${myapp.base}/lib,${myapp.base}/bin 

可能有任何數量的其他路徑上線。
$ {myapp.base}已經在文件中定義,不需要擔心它擴展到什麼。

我試圖用標準的shell腳本命令來做到這一點。 我想用sed,我可以做得更緊湊。

回答

0

你可以做到這一點與awk腳本如下:

#!/bin/bash 

awk '{printf "%s", $0} 
    !/\$\{myapp\.base\}\/bin/ {printf "%s", ",${myapp.base}/bin"} 
    {print ""}' input_file > output_file 

輸入:

checkedpaths=${myapp.base}/lib 
checkedpaths=${myapp.base}/bin,someotherstuff 

輸出:

checkedpaths=${myapp.base}/lib,${myapp.base}/bin 
checkedpaths=${myapp.base}/bin,someotherstuff 

說明:

  • awk:調用awk命令
  • '...':一切由單引號括將由AWK
  • {printf "%s", $0}運行:對於每個行,按原樣打印,但不要以換行符
  • !/\$\{myapp\.base\}\/bin/ {printf ",${myapp.base}/bin"}:如果圖案${myapp.base}/bin與當前行上的任何位置匹配,則打印,${myapp.base}/bin(因爲我們在最後一步中沒有用換行符終止行,所以會將其追加到同一行的末尾。)
  • {print ""}:現在使用換行符char終止當前行,而不管該模式是否匹配。
  • input_file > output_file:使用input_file作爲輸入;輸出重定向到output_file
+0

考慮包含'$ {myapp.base}/binary'的行。 –

+0

另外,「。」是一個RE元字符,所以您需要將其轉義,您可能還需要根據awk版本轉義{和}。最後,使用print「」而不是printf「\ n」,並且printf的synposis是'printf fmt,text',所以如果有任何格式化字符潛入「text」,那麼使用printf而不是'printf text'。 –

+0

@EdMorton:謝謝埃德,你的代碼評論總是對我的學習有很大的幫助。 –

2

你應該能夠做到:

sed '/checkedpaths/{ \@${myapp.base}/[email protected][email protected][email protected],${myapp.base}/[email protected] }' 

這不替換該文件的內容:要麼重定向或使用-i。此外,這不是特別健壯,並且不會將文本附加到包含${myapp.base}/binary的行,但如果是問題,則很容易修復。

+0

我需要使用比sed的其他東西,以確定是否$ {} myapp.base /二進制已上線?或者可以以某種方式構建到搜索標準中 - 如果它在那裏找到並且沒有做任何事情,它會失敗? –

+0

@GeorgeHernando - 這是一個問題嗎? – tjameson

+0

您可以使用sed,但您需要更改'{'中的第一個檢查以防止短匹配。不幸的是,sed不允許'[,$]'表示「逗號或行尾」,所以你需要做一些醜陋的事情,比如:'\ @ [:,] $ {myapp.base}/bin \ | $ \)@' –

0

不使用sed但只有bash,你可以使用:

if [[ $myvar != *tobeappended* ]] 
then 
    myvar=$myvar,tobeappended 
fi 
+0

會以許多不同的方式失敗...... –

+0

絕對是。但是由於提到的問題「正在嘗試使用標準shell腳本命令[...]」來實現,所以我認爲OP至少會得到一個非''''答案是有趣的。 –

2
awk '{print $0 (/\$\{myapp\.base\}\/bin(,|$)/ ? "" : "${myapp.base}/bin")}' file