Recebi um script% post dentro de um arquivo de especificações para editar um arquivo de configuração (chamado foo). Recebi a tarefa de escrever outro script quase idêntico para editar um arquivo chamado 'bar'.
Embora minha solução para 'bar' funcione tecnicamente, ela é dramaticamente diferente semanticamente. O zelador está solicitando que eu o reescreva para manter a consistência.
foo.groovy antes
messageQueue.secretKey = "<ENTER-KEY-HERE>"
foo.groovy depois
messageQueue.secretKey = "y775hUYKR1Bm4gUWNRbzqg65"
O script que me foi dado é o seguinte:
%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
O que estou tentando descobrir:
- O que esse regex faz?
s?^//\s*??"
Presumo que esteja procurando um sinal de igual. - Qual é o propósito das barras finais?
\\\
- Por que o autor anterior colocou a expressão entre colchetes
{ }
?
Para referência, aqui está meu script (para bar), que estou tentando reescrever para corresponder ao script acima (para foo)
bar.groovy antes
clientSecret:"<ENTER-CLIENTSECRET-HERE>",
bar.groovy depois
clientSecret:"4gUWNRbzqg65y775hUYKR1Bm",
script de barra
%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
Responder1
Em qualquer linha que contenha a string, messageQueue.secretKey
ele remove a string //
e quaisquer espaços que a seguem, se existirem no início da linha, e substitui a primeira ocorrência de <ENTER-KEY-HERE>
pelo conteúdo da variável shell ${MESSAGEQUEUESECRETKEY}
. Os {
curlies limitam as remoções/substituições aapenaslinhas contendo a string messageQueue.secretKey
. Essas operações são executadas no arquivo referenciado pela variável shell${config_file}.
As \\\
barras invertidas continuam a instrução em uma linha longa - escapando do caractere ewline imediatamente seguinte \n
quando o script é lido pelo shell. Três são necessários porque estão contidos entre "
aspas duplas e a barra invertida escapa sozinha nesse contexto. Portanto, o shell obtém uma nova linha de escape e sed
uma nova linha de escape. Porém, embora eu não saiba sobre o shell neste contexto, não acredito que sed
se importaria se as novas linhas não escapassem de qualquer maneira.
Responder2
- O que esse regex faz?
s?^//\s*??"
Remova o //
e quaisquer espaços seguintes do início da linha nas linhas que contêm messageQueue.secretKey com:
- o ponto de interrogação
?
como delimitador de padrão ^
corresponde ao início de uma linha//
corresponde exatamente a isso (em uma observação lateral, esse é o motivo para usar o ponto de interrogação como delimitador de padrão em vez do mais comum,/
o que evita um pouco de escape, porque caso contrário, o regex serias/^\/\/\s*//
\s*
é específico do GNU sed para corresponder ou mais espaços em branco spacee/ou Tab; POSIX sed usaria[:space:]
E @mikeserv acaba de postar uma resposta ainda mais abrangente...