我在规范文件中提供了一个 %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 刚刚发布了一个更全面的答案......