As citações não delimitam campos.
Este é um aspecto importante, mas muitas vezes esquecido, da sintaxe da linguagem shell. O modelo mental que alguém "cita argumentos" é, de fato, simplista e errado. Alguém cita coisas que precisam ser citadas, e isso precisa ser apenas uma parte do que acaba sendo um único argumento.
E é exatamente isso que você precisa fazer aqui. Ironicamente, a primeira resposta agora excluída foi muito próxima .
A string final que você deseja dar a sed
como o único argumento real com o qual ele é executado é
/user:/!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tpassword: \x27!!\x27/gcom a parte
user
variando de acordo com o nome do usuário real. Mas para chegar até aqui você não precisa usar um único esquema de cotação para o argumento inteiro. Você pode construir o argumento a partir de partes.
Use aspas duplas para a parte em que você precisa que a expansão do parâmetro ocorra e aspas simples para as partes em que você precisa expandir o histórico para não ocorrer:
while read -r i do sed -e '/'"$i"':/!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tpassword: \x27!!\x27/g' puppet-users.yaml > puppet-users{new}.yaml mv puppet-users{new}.yaml puppet-users.yaml done < user_list.txt
Isto é:
- O caractere com aspas simples
/
. - Os caracteres com aspas duplas
$i
, que estão sujeitos à expansão de parâmetros (e, é claro, a todas as outras expansões e substituições). - Os caracteres com aspas simples
:/!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tpassword: \x27!!\x27/g
que não estão sujeitos à expansão do histórico.
A divisão de campos ocorre apenas em caracteres não citados; e não há nenhum aqui, então este é todo um campo , que se torna todo um argumento para o comando sed
.
Depois de fazer isso, você descobrirá que usou muitos caracteres TAB no que está fazendo. ☺
Na mão emocionante ...
sed
não é a ferramenta certa para esse trabalho. Também não é awk
, como na segunda resposta agora excluída. Analisar o YAML usando um analisador YAML adequado, como o módulo yaml do Python, será melhor a longo prazo, se a tarefa em questão se tornar menos trivial, como provavelmente acontecerá.
E este é um simples one-liner com uma ferramenta adequada para o trabalho, como várias ferramentas yq
, cujo uso será mais ou menos (desde que, infelizmente, todas elas diferem):
while read -r i do yq < puppet-users.yaml "$i".password="'\!\!'" > puppet-users{new}.yaml mv puppet-users{new}.yaml puppet-users.yaml done < user_list.txt