Editando um arquivo de propriedades Java com o Bash

2

Eu tenho o seguinte arquivo de propriedades Java que é mantido por seres humanos.

# file.input = /very/old/name
# file.input = /old/name
file.input = /current/name
file.input.default = /default/name
other.file.input = /current/other/name
# Other comments
other.properties = must stay the same

Eu preciso criar um script que edite esse arquivo sem tocar no resto dos arquivos. Portanto, não posso descarregar novas propriedades no arquivo de configuração.

Os humanos geralmente copiam / colam uma linha e comentam para uso posterior. Meu aplicativo deve editar exclusivamente o arquivo de configuração sem tocar em nenhum dos comentários.

Neste caso específico, quero editar a linha file.input para definir o valor como /new/name sem nenhuma linha comentada ser tocada e sem que outras propriedades também sejam tocadas ( file.input.default , other.file.input ). Meu script não manterá a linha atual para fins de história, como os humanos costumam fazer. Além disso, não sei o valor atual definido para a chave file.input .

Onde estou preso? Bem no começo. Eu não sou um especialista em Bash, eu raramente uso, exceto para chamar comandos em sequência e eu uso alguns ifs às vezes. Mas isso é tudo.

Eu poderia usar perl para usar expressões regulares, mas o perl aparentemente não está instalado neste sistema. Então, voltei para sed , mas não consigo nada disso: parece que posso substituir apenas um valor específico por outro. Eu poderia embrulhar isso na leitura do arquivo e reescrevê-lo, exceto pela linha esperada que eu poderia mudar. Além disso, eu mal seria capaz de lidar com espaços humanos adicionados na frente da propriedade que eu quero mudar.

Então, se você tiver uma alternativa, compartilhe-a, porque eu começo a ficar alienada.

    
por Olivier Grégoire 08.04.2014 / 11:00

3 respostas

5

Usando a opção -i de sed (que edita no local). A ressalva é o caractere usado para delimitar o comando de substituição não deve aparecer na cadeia NEW. O exemplo usa ':' em vez de '/' para delimitar ( s:old_string:new_string: )

NEW=/new/name    
sed -i 's:^[ \t]*file.input[ \t]*=\([ \t]*.*\)$:file.input = '${NEW}':' f
    
por 08.04.2014 / 11:18
2

Uma solução usando awk :

$ awk -F'=' '$1 ~ /^[ \t]*file.input[ \t]*$/{$2="= /new/name"}{print}' config
# file.input = /very/old/name
# file.input = /old/name
file.input = /new/name
file.input.default = /default/name
other.file.input = /current/other/name
# Other comments
other.properties = must stay the same

Depois, você pode salvá-lo no novo arquivo de configuração:

awk -F'=' '$1 ~ /^\s*file.input\s*$/{$2="= /new/name"}{print > "new_config"}' config

    
por 08.04.2014 / 11:18
0

Observe que se você precisar disso em um script para trabalhar em várias plataformas (para trabalhar no MacOSX também), será necessário usar o sinalizador -i completo, fornecendo uma extensão de arquivo de backup:

NEW=/new/thing
sed -i.backup 's|\s*file.input\s*=.*$|file.input = '${NEW}'|' filename

## Then you can check exit code and remove the backup file if all is well
## rm filename.backup

Caso contrário, no MacOSX, você receberá um erro como "caracteres extras no final do comando".

    
por 06.03.2018 / 16:39