Tenho um Jenkinsfile que analisa um servidor local de artefatos em busca de novas versões do arquivo pai e das dependências. Quando confirmo que há uma nova versão, quero substituir a versão antiga por uma nova.
então dado um pom.xml contendo esta dependência:
<dependency>
<groupId>abcde</groupId>
<artifactId>xyz</artifactId>
<version>1.2.4</version>
</dependency>
... e suponha que haja uma versão mais recente 1.3.5 do abcde.xyz...
Gostaria de atualizar isso com o seguinte comando sed:
sed -i '/<dependency>/,/<\/dependency>/{
/<groupId>abcde<\/groupId>/{
/<artifactId>xyz<\/artifactId>/{
s/<version>1.2.4<\/version>/<version>1.3.5<\/version>/
}
}
}' pom.xml
Se eu criar um pom.xml contendo o xml acima ou somente o xml acima e executar essa instrução, o arquivo será modificado, mas nada mudará. A remoção do -i
sinalizador basicamente despeja o arquivo 1:1 na saída padrão - o que estou perdendo?
saída esperada:
<dependency>
<groupId>abcde</groupId>
<artifactId>xyz</artifactId>
<version>1.3.5</version>
</dependency>
(No jenkinsfile ele é parametrizado e escapado como abaixo, mas como a instrução básica não está funcionando, concentre-se nisso.)
sh """
sed -i '/<dependency>/,/<\\/dependency>/{
/<groupId>${groupId}<\\/groupId>/{
/<artifactId>${artifactId}<\\/artifactId>/{
s/<version>${version}<\\/version>/<version>${targetVersion}<\\/version>/
}
}
}' pom.xml
"""
Se você fizer isso diretamente em um shell,
sed 's/${groupId}/foo/'
agroupId
variável não será expandida, pois está entre aspas simples. Isso também pode ocorrer quando você a encapsula,sh """ ... """
como faz com o que quer que esteja executando ("jenkinsfile"?), não sei./<dependency>/,/<\/dependency>/{ foo }
significa "para cada uma das linhas de/<dependency>/
para/<\/dependency>/
fazerfoo
". Então, você isola o bloco de linhas em que está interessado, masfoo
ainda aplica uma linha de cada vez dentro desse bloco. Você faz/<groupId>abcde<\/groupId>/
o que corresponde àquela linha e tenta fazer/<artifactId>xyz<\/artifactId>/
dentro daquela linha , mas<artifactId>
não existe na mesma linha que<groupId>
e, portanto, nunca fará nada.Você pode fazer isso de forma fácil, mais robusta e sem duplicar nenhuma das expressões de início/fim de bloco com awk, por exemplo, usando uma pequena máquina de estados com GNU awk for
-i inplace
(o que eu presumo que você tenha, já que está usando GNU sed):Além de fazer o que você pediu para resolver o problema que você teria com o sed sendo incapaz de fazer comparações de strings literais e, portanto, exigindo que você escapasse todos os metacaracteres regex, delimitadores sed e referências retroativas, veja É possível escapar metacaracteres regex de forma confiável com sed .
Atualizar endereços sed para incluir as linhas restantes até
</dependency>
resolver o problemaO cifrão também pode ser usado em endereços internos para indicar o fim do espaço ativo e
/
o separador nos
comando pode ser substituído por outro caractere para reduzir o escape