
ACTUALIZAR:
- La respuesta REAL a esta pregunta MULTILINEA la dio aquí Stéphanehttps://unix.stackexchange.com/a/521560/354415
- Alternativamente, vaya línea por línea con perl de Terdon a continuación:https://unix.stackexchange.com/a/521512/354415
- 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 sed
código simplemente aplica la sustitución a todas las líneas que no comienzan con un #
carácter.