
ATUALIZAR:
- A resposta REAL para esta pergunta MULTILINE foi dada aqui por Stephanehttps://unix.stackexchange.com/a/521560/354415
- Alternativamente, vá linha por linha com perl de Terdon abaixo:https://unix.stackexchange.com/a/521512/354415
- Alternativamente, vá linha por linha com o IFS aqui:https://unix.stackexchange.com/a/521550/354415
Aqui está meu novo brinquedo:
O problema é que quero que corresponda apenas em linhas que não possuem #\s* na frente do parâmetro.
Por favor, não forneça código alternativo, por exemplo, sed etc. use perl
perl -we 'my $file= "parameter=9
# parameter=10
parameter=10
"; $file=~ s/.*((?<!^# ))parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'
Resultado esperado
parameter=replaced
# parameter=10
parameter=replaced
PS se você estiver interessado em ver como progredi com isso, veja aqui:Perl Negative Lookbehind com desvio de comprimento variável, talvez?
Responder1
Isso é complicado pela sua escolha de passar a string multilinha como uma única variável. é muito mais fácil simplesmente converter isso em um array para que você possa usar o s///
operador em sua forma mais simples. Tente isto: você disse que não está interessado em melhorias de código, mas para ajudar futuros usuários, aqui está uma versão simplificada do que você escreveu, que também evita a má prática de usar ALLCAPS para variáveis que não são de ambiente:
newparameter='parameter=replaced'
filesection='
parameter=9
# parameter=10
parameter=10
'
matchparamperl='^([^#]*)parameter\s*=.*'
sectionfixed=$( perl -le '
@lines=split(/\n/,$ARGV[0]);
s/$ARGV[1]/$1$ARGV[2]/g for @lines;
print join "\n", @lines
' "$filesection" "$matchparamperl" "$newparameter")
echo "$sectionfixed"
Isso retornará:
$ echo "$sectionfixed"
parameter=replaced
# parameter=10
parameter=replaced
Alternativamente, um pouco mais curto:
sectionfixed=$( perl -le '
do{
s/$ARGV[1]/$1$ARGV[2]/g; print
} for split(/\n/,$ARGV[0])
' "$filesection" "$matchparamperl" "$newparameter")
Responder2
perl -we 'my $file= "parameter=9
# parameter=10
parameter=10
"; $file=~ s/.*((?<!# ))parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'
Assim que se faz )))
Saída:
parameter=replaced
# parameter=10
parameter=replaced
Chamado Lookbehind Negativo http://www.blackwasp.co.uk/RegexLookahead.aspx
Obrigado a Kusalananda por fornecer a ideia.
Eu nunca teria pensado nisso.
Responder3
contents='
parameter=9
# parameter=10
parameter=10
'
sed '/^#/!s/parameter[[:blank:]]*=.*/parameter=replaced/' <<<"$contents"
Saída:
parameter=replaced
# parameter=10
parameter=replaced
O sed
código está simplesmente aplicando a substituição a todas as linhas que não começam com um #
caractere.