pt sed substituir vários padrões com determinada string

1

Eu fui encarregado de substituir um monte de IDs codificados em algum código (por exemplo: private static String MERCHANT_ID = "1234"; ) com referências a um arquivo de configuração em algum lugar (então a versão substituída para este exemplo deve ser private static String MERCHANT_ID = ConstantMerchants.MERCHANT_A; ). / p>

A função padrão de localizar e substituir no Eclipse seria bem se eu estivesse substituindo apenas algumas ID's, mas não estou. Eu tenho vinte projetos, todos eles contêm centenas de arquivos com várias notações diferentes da cadeia antiga.

Eu já compilei uma lista de padrões de regex que correspondem a todas as notações possíveis.

Existe uma maneira de usar o sed para substituir todas as strings antigas pelas novas versões, tendo um arquivo de configuração em algum lugar contendo o padrão antigo, e com o que ele deve ser substituído?

Estou à procura de algo que me permita definir padrões com um novo valor, pense em algo semelhante a isto: (mas depois com muito mais ID's)

# old | new
/merchantId:\s*("|')1234("|'),/|merchantId: ConstantMerchants.MERCHANT_A
/private static String MERCHANT_ID\s*=\s*("|')1234("|');/|private static String MERCHANT_ID = ConstantMerchants.MERCHANT_A

Se eu precisar usar outra ferramenta que me ajude a resolver melhor esse problema, adoraria saber disso. Eu gostaria muito de usar o novo recurso Bash on Windows, mas isso é só porque parece legal:)

    
por cascer1 10.10.2016 / 13:17

2 respostas

2

Pelo que entendi, o problema é que você tem um conjunto de padrões de sintaxe para combinar e, de forma independente, muitos números possíveis que precisam ser traduzidos, e você precisa "multiplicar" esses números juntos. O seguinte pode ser um mecanismo sed adequado, supondo alguma simplificação: no seu sed use primeiro os padrões para corresponder às linhas e, em seguida, use a conversão do número nessas linhas. Por exemplo, crie um arquivo sedscript holding

/merchantId:\s*("|')[0-9]+("|')/b change
/private static String MERCHANT_ID\s*=\s*("|')[0-9]+("|')/b change
b
:change
s/["']1234["']/ConstantMerchants.MERCHANT_A/
s/["']1235["']/ConstantMerchants.MERCHANT_B/

Começa com cada um dos seus padrões, seguido pelo comando b change , o que significa ramificar para o rótulo change quando o padrão é encontrado. A lista de padrões termina com o comando b , o que significa ramificar até o final, ou seja, seguir em frente para ler a próxima linha de entrada do arquivo.

O :change significa que esse é o rótulo change para o qual nos direcionamos. Em seguida, segue cada um dos seus possíveis números para nomear traduções. A simplificação é assumir que apenas um número entre aspas aparecerá na linha, para que possamos ignorar qual padrão real correspondeu. Se houver algumas exceções, pode valer a pena manipulá-las manualmente.

Em um sistema Unix (eu não sei sobre windows) você pode usar este shell script para editar os arquivos:

find dir -type f |
xargs sed -i -r -f sedscript

O -i edita os arquivos no local, então sempre começa copiando os arquivos para um novo diretório dir , em seguida, executa este comando na cópia e usa diff -ru entre os dois diretórios para verificar se está fazendo o que você deseja. O -r é necessário (no Unix) para que o GNU sed aceite (a|b) em vez do padrão usual \(a\|b\) .

    
por 10.10.2016 / 20:02
1

Ao olhar para a Página MAN você verá que sed suporta% parâmetro-f para fornecer um arquivo de script. Esse arquivo deve conter todas as substituições a serem executadas, pois você as forneceria a sed diretamente. Então, por exemplo, você teria:

  • s/old/new/
  • s/new/old/

Em linhas separadas no arquivo e aplicaria ambos os comandos ao que você fornecer por stdout . Como exemplo: echo "old" | sed -f script.file com o conteúdo acima levaria à saída antiga.

Para aplicar essas regras a vários arquivos, uma opção seria usar um loop no qual você executa sed com o script de cada arquivo e salva as alterações no próprio arquivo. Outra seria usar a opção -i e fornecer "todos" os arquivos como argumentos de linha de comando. Dependendo do número, você pode encontrar problemas com o comprimento total do comando.

    
por 10.10.2016 / 14:25