
Eu tenho esse código simples
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")'
e quero substituir todos os parâmetros = 10, mas não se for precedido por um hash em qualquer lugar dessa linha. por exemplo
# parameter=10
# parameter=10
# parameter=10
parameter=replaced
parameter=replaced
eu sei que se eu fornecer um
((?<!#\s*))
Eu recebo um erro
Lookbehind de comprimento variável não implementado em regex
Então, existe uma maneira de realizar a tarefa por outros meios?
Obrigado
Responder1
Você pode fazer algo como:
s/#.*|((?<!\S)parameter\h*=.*)/$1 ? "parameter=replaced" : $&/ge;
A ideia é que o #.*
(que substituímos por si mesmo) elimine todos os comentários. E na segunda parte da alternância, procuramos o seu padrão (aqui parameter=...
desde que não seja precedido por um espaço que não seja em branco) no que resta.
Outra abordagem é usar:
s/^[^#\n]*\K(?!<\S)parameter\h*=.*/parameter=replaced/gm;
\K
define o início da peça a ser substituída. A m
bandeira ^
corresponde no início de cada linha dentro do assunto.
Se eles parameter=
forem encontrados apenas no início das linhas (seguidos de espaços em branco opcionais), então isso é apenas:
s/^\h*\Kparameter\h*=.*/parameter=replaced/gm;
Responder2
Bem, a única alternativa que consegui encontrar é 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"
Saída:
# parameter=10
# parameter=10
# parameter=10
parameter=replaced
parameter=replaced
Temos que usar '^(?!#+$)(\s*)'
lookahead negativo linha por linha. E aceita comprimentos variáveis (talvez porque não esteja em uma string multilinha? ainda não sei).
Me deparei com essa ideiahttps://www.regextester.com/95226e finalmente consegui.
Eu aprendi algo novo hoje. Espero que você ache isso útil!
PS. também poderíamos usar um simples ([^#]*)
como sugerido porterdon https://unix.stackexchange.com/a/521512/354415que sugeriu basicamente o mesmo conceito que aqui, mas implementado em um perl one liner! muito legal !