我在規範文件中提供了一個 %post 腳本來編輯設定檔(稱為 foo)。我的任務是編寫另一個幾乎相同的腳本來編輯名為“bar”的檔案。
雖然我的“bar”解決方案在技術上可行,但在語義上卻截然不同。保管人要求我重寫它以保持一致性。
之前的 foo.groovy
messageQueue.secretKey = "<ENTER-KEY-HERE>"
foo.groovy 之後
messageQueue.secretKey = "y775hUYKR1Bm4gUWNRbzqg65"
給我的腳本如下:
%define oauth_client_Secret \
echo " Setting the message queue secret key..." \
MESSAGEQUEUESECRETKEY=`dd if=/dev/urandom count=16 bs=1 2>/dev/null | base64` \
for config_file in `find /opt/foo/etc -name *.groovy` \
do \
sed -i -e "/messageQueue.secretKey/ { " \\\
-e " s?^//\s*??" \\\
-e " s?<ENTER-KEY-HERE>?${MESSAGEQUEUESECRETKEY}?" \\\
-e "}" \\\
${config_file} \
done
我想弄清楚的是:
- 這個正規表示式有什麼作用?
s?^//\s*??"
我認為它正在尋找等號? - 尾部斜杠的目的是什麼?
\\\
- 為什麼前作者將表達式括在括號中
{ }
?
作為參考,這是我的腳本(針對 bar),我正在嘗試重寫以匹配上面的腳本(針對 foo)
之前的 bar.groovy
clientSecret:"<ENTER-CLIENTSECRET-HERE>",
酒吧.groovy 之後
clientSecret:"4gUWNRbzqg65y775hUYKR1Bm",
酒吧腳本
%define oauth_client_Secret \
echo " Generating oauth clientSecret..." \
MESSAGEQUEUESECRETKEY=`dd if=/dev/urandom count=16 bs=1 2>/dev/null | base64` \
for config_file in `find /opt/bar/etc -name *.groovy` \
do \
sed -i "s/<ENTER-CLIENTSECRET-HERE>/${MESSAGEQUEUESECRETKEY}/g" ${config_file} \
done
答案1
在包含該字串的任何行上,如果該字串和其後的空格存在於該行的開頭,則messageQueue.secretKey
它會刪除該字串,並用 shell 變數的內容替換第一次出現的。花邊將刪除/替換限制為//
<ENTER-KEY-HERE>
${MESSAGEQUEUESECRETKEY}
{
僅有的包含字串 的行messageQueue.secretKey
。這些操作是在shell變數引用的檔案上執行的${config_file}.
反斜線\\\
將語句延續到一長行 -\n
當 shell 讀入腳本時轉義緊接著的 ewline 字元。三個是必要的,因為它們包含在"
雙引號內,並且反斜線在該上下文中會自行轉義。因此,shell 獲得一個轉義換行符並sed
獲得一個轉義換行符。不過,雖然我不知道這種情況下的外殼,但我不相信sed
會關心換行符是否根本沒有被轉義。
答案2
- 這個正規表示式有什麼作用?
s?^//\s*??"
刪除//
包含 messageQueue.secretKey 的行開始處的 和後面的任何空格:
- 問號
?
作為模式分隔符 ^
匹配行的開頭//
完全匹配(順便說一句,這就是使用問號作為模式分隔符號而不是更常見的原因,/
這可以防止相當多的轉義,因為否則正則表達式將是s/^\/\/\s*//
\s*
GNU sed 是否特定於匹配或多個空格space和/或Tab; POSIX sed 將會使用[:space:]
@mikeserv 剛剛發布了一個更全面的答案...