
tengo este código simple
perl -we 'my $file= "
# parameter=10
# parameter=10
# parameter=10
parameter=10
parameter=10
"; $file=~ s/((?<!# ))\s*parameter\s*=.*/parameter=replaced/g; print(":$file:\n")'
y quiero que reemplace todos los parámetros = 10, pero no si está precedido por un hash en cualquier parte de esa línea. p.ej
# parameter=10
# parameter=10
# parameter=10
parameter=replaced
parameter=replaced
Sé que si proporciono un
((?<!#\s*))
me sale un error
Búsqueda hacia atrás de longitud variable no implementada en expresiones regulares
Entonces, ¿hay alguna manera de realizar la tarea por algún otro medio?
Gracias
Respuesta1
Puedes hacer algo como:
s/#.*|((?<!\S)parameter\h*=.*)/$1 ? "parameter=replaced" : $&/ge;
La idea es que #.*
(que reemplazamos por sí mismo) elimine todos los comentarios. Y en la segunda parte de la alternancia, buscamos su patrón (aquí parameter=...
siempre que no esté precedido por un espacio que no sea en blanco) en lo que queda.
Otro enfoque es utilizar:
s/^[^#\n]*\K(?!<\S)parameter\h*=.*/parameter=replaced/gm;
\K
establece el inicio de la pieza a reemplazar. La m
bandera coincide ^
al comienzo de cada línea dentro del asunto.
Si parameter=
solo se encuentran al comienzo de las líneas (seguidos de espacios en blanco opcionales), entonces eso es solo:
s/^\h*\Kparameter\h*=.*/parameter=replaced/gm;
Respuesta2
Bueno, la única alternativa que se me ocurre es esta:
FILESECTION="\
# parameter=10
# parameter=10
# parameter=10
parameter=10
parameter=10
"
newfile=''
while IFS= read -r line ;
do
SECTIONFIXED=$( perl -le '$file=$ARGV[0]; $file=~ s/^(?!#+$)(\s*)(parameter\s*=.*)/parameter=replaced/g; print("$file\n");' "${line}" ; )
newfile=$( printf "${newfile}\n${SECTIONFIXED}\n" )
done <<< "$FILESECTION"
echo "$newfile"
Producción:
# parameter=10
# parameter=10
# parameter=10
parameter=replaced
parameter=replaced
Tenemos que utilizar '^(?!#+$)(\s*)'
una búsqueda anticipada negativa línea por línea. Y acepta longitudes variables (¿tal vez porque no está en una cadena de varias líneas? Aún no lo sé).
me encontré con esta ideahttps://www.regextester.com/95226y finalmente lo puse en marcha.
Aprendí algo nuevo hoy. ¡Espero que encuentres esto útil!
PD. También podríamos usar un simple ([^#]*)
como lo sugiereterdón https://unix.stackexchange.com/a/521512/354415¡Quién sugirió básicamente el mismo concepto que aquí pero implementado en una sola línea de Perl! muy lindo !