Correspondência multilinha Perl para 'algo' que começa sem '#\s'

Correspondência multilinha Perl para 'algo' que começa sem '#\s'

ATUALIZAR:

  1. A resposta REAL para esta pergunta MULTILINE foi dada aqui por Stephanehttps://unix.stackexchange.com/a/521560/354415
  2. Alternativamente, vá linha por linha com perl de Terdon abaixo:https://unix.stackexchange.com/a/521512/354415
  3. 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 sedcódigo está simplesmente aplicando a substituição a todas as linhas que não começam com um #caractere.

informação relacionada