2017-04-14 59 views
1

隨着SED的內容替換模式的第一次出現,我試圖取代第一發生的註釋中的腳本,如:桑達/ awk中:與另一個文件

#ENTRYPOINT_CONTENT

將第二個文件($ file_content)的內容轉換爲另一個第三個文件(/base.sh)。

因此,根據很多文檔,該字符串應該是很簡單的,是這樣的:

sed "s|\#ENTRYPOINT_CONTENT|$file_content|" /base.sh

但我總是喜歡錯誤結束:

sed: -e expression #1, char 23: unterminated s' command

或類似消息,也嘗試了不同的分隔符,即使使用Awk代替,但沒有成功,在搜索模式中轉義#後似乎沒有問題,但仍然無法將文件內容作爲變量le在Sed。

任何想法,無論是與Sed或Awk?

編輯:--------------------

@Sundeep @詹姆斯布朗:

不想混科目也不會太長:)在本次編輯結束時,對你澄清請求的迴應以粗體顯示,但僅僅爲了詳細說明上下文,我的情況是在bash中的Docker入口點腳本(用於基本Docker鏡像),稱爲/root/test/base

#!/usr/bin/env bash 

#ENTRYPOINT_CONTENT 

if [[ -e "/root/test/custom" ]]; then 

    printf "\n\n#ENTRYPOINT_CONTENT\n" >> /root/test/custom 

    # Code from whjm's reply below (actually works but appends shebangs from custom files) 
    sed -e '0,/^#ENTRYPOINT_CONTENT/!b; /^#ENTRYPOINT_CONTENT/{ r /root/test/custom' -e 'd; }' /root/test/base.sh >> /root/test/base2.sh 

    mv /root/test/base2.sh /root/test/base.sh 
    rm -f /root/test/custom 

fi 

我只想讓用戶自己砸自己的另一bash腳本的特定路徑上(比如說/root/test/定製),例如:

#!/usr/bin/env bash 
echo 'My 2nd bash code' 

以上(基地)第一個腳本應插入內容在定製文件在#ENTRYPOINT_CONTENT位置(在基本腳本本身,不刪除此搜索字符串),像這樣:

#!/usr/bin/env bash 

echo 'My 2nd bash code' 

#ENTRYPOINT_CONTENT 

if [[ -e "/root/test/custom" ]]; then 

    printf "\n\n#ENTRYPOINT_CONTENT\n" >> /root/test/custom 

    # Code from whjm's reply below 
    sed -e '0,/^#ENTRYPOINT_CONTENT/!b; /^#ENTRYPOINT_CONTENT/{ r /root/test/custom' -e 'd; }' /root/test/base.sh >> /root/test/base2.sh 

    mv /root/test/base2.sh /root/test/base.sh 
    rm -f /root/test/custom 

fi 

如果另一個用戶後滴肛在相同的路徑療法自定義腳本,我們應該有附加這樣的第三自定義腳本的代碼:

#!/usr/bin/env bash 
echo 'My 2nd bash code' 
echo 'My 3rd bash code' 
#ENTRYPOINT_CONTENT 

if [[ -e "/root/test/custom" ]]; then 
# ... and so on 

關於從自定義文件的shebangs,它不是一個真正的問題,如果他們被追加到基本文件, @whjm的sed代碼按預期工作,但會追加它們,而令人驚訝的是@James Brown的兩個awk代碼已經(並優雅地)忽略了自定義文件中的所有額外shebang(可能是因爲它們也以#開頭,作爲#ENTRYPOINT_CONTENT搜索字符串),但目前部分preprend像代碼:

#!/usr/bin/env bash 
echo 'My 3rd bash code' 
echo 'My 2nd bash code' 
#ENTRYPOINT_CONTENT 

當我試圖把它附加像:

#!/usr/bin/env bash 
echo 'My 2nd bash code' 
echo 'My 3rd bash code' 
#ENTRYPOINT_CONTENT 

因此,簡而言之,@Sundeep,如果你能不能給我的這個您AWK代碼的更新版本,這將是完美的! :D(找不到方法來顛倒這個......)非常感謝。從以前的帖子

代碼:

NR==FNR { b=b (FNR==1?"":ORS) $0; next } 
{ r=r (FNR==1?"":ORS) $0 } #ENTRYPOINT_CONTENT 
END { sub(/\#[^\n]+/,r,b); print b} 
+0

你會得到錯誤,如果'$ file_content'有換行符,則'|'字符,等等...如果你可以添加一個小小的'base.sh'和'file_content'內容,它將有助於爲你提供一個解決方案......尤其是創建一個包含多個'#ENTRYPOINT_CONTENT'的示例並顯示期望的輸出 – Sundeep

+0

@Sundeep:我在上面編輯的答案 – glc

回答

0

如果您使用GNU sed的:

[STEP 101] # cat file1 
11 
xx // replace me 
44 
xx // don't replace me 
55 
[STEP 102] # cat file2 
22 
33 
[STEP 103] # sed -e '0,/^xx/!b; /^xx/{ r file2' -e 'd }' file1 
11 
22 
33 
44 
xx // don't replace me 
55 
[STEP 104] # 
+0

非常棒!非常感謝 !對於其他讀者,上面代碼中的'xx'是要搜索和替換的字符串(在我的情況下是'#ENTRYPOINT_CONTENT') – glc