Coincidencia multilínea de Perl para 'algo' que comienza sin '#\s'

Coincidencia multilínea de Perl para 'algo' que comienza sin '#\s'

ACTUALIZAR:

  1. La respuesta REAL a esta pregunta MULTILINEA la dio aquí Stéphanehttps://unix.stackexchange.com/a/521560/354415
  2. Alternativamente, vaya línea por línea con perl de Terdon a continuación:https://unix.stackexchange.com/a/521512/354415
  3. Alternativamente, vaya línea por línea con IFS yo solo aquí:https://unix.stackexchange.com/a/521550/354415

Aquí está mi nuevo juguete:

El problema es que quiero que coincida solo en líneas que no tienen #\s* delante del parámetro.

No proporcione ningún código alternativo, por ejemplo, sed, etc., utilice perl.

perl -we 'my $file= "parameter=9
# parameter=10
parameter=10
"; $file=~ s/.*((?<!^# ))parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'

Rendimiento esperado

parameter=replaced
# parameter=10
parameter=replaced

PD: si estás interesado en ver cómo progresé con esto, mira aquí:¿Quizás Perl Negative Lookbehind con derivación de longitud variable?

Respuesta1

Esto se complica por su elección de pasar la cadena de varias líneas como una única variable. es mucho más fácil convertir eso en una matriz para poder usar el s///operador en su forma más simple. Pruebe esto: dijo que no está interesado en mejoras de código, pero para ayudar a futuros usuarios, aquí hay una versión simplificada de lo que escribió que también evita la mala práctica de usar ALLCAPS para variables que no son de entorno:

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"

Eso volverá:

$ echo "$sectionfixed"

   parameter=replaced
# parameter=10
parameter=replaced

Alternativamente, un poco más corto:

sectionfixed=$( perl -le '
                         do{
                            s/$ARGV[1]/$1$ARGV[2]/g; print
                         } for split(/\n/,$ARGV[0])
                         ' "$filesection" "$matchparamperl" "$newparameter")

Respuesta2

perl -we 'my $file= "parameter=9
# parameter=10
parameter=10
"; $file=~ s/.*((?<!# ))parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'

Así es como se hace)))

Producción:

parameter=replaced
# parameter=10
parameter=replaced

Llamado mirar hacia atrás negativo http://www.blackwasp.co.uk/RegexLookahead.aspx

Gracias a Kusalananda por aportar la idea.

Nunca lo hubiera pensado.

Respuesta3

contents='
   parameter=9
# parameter=10
parameter=10
'

sed '/^#/!s/parameter[[:blank:]]*=.*/parameter=replaced/' <<<"$contents"

Producción:

   parameter=replaced
# parameter=10
parameter=replaced

El sedcódigo simplemente aplica la sustitución a todas las líneas que no comienzan con un #carácter.

información relacionada