Coincide com um padrão e substitua a primeira instância da sequência seguinte

3

Estou programando a modificação de um arquivo de configuração assim:

[purple]
auth = no
enabled = 0
username = 
password =
priority = 0
host = True

[shovel]
group = 
manual = False
enabled = 0
username = 

Onde existem muitas [categorias] e, às vezes, com a mesma chave de um par de chave / valor.

É possível criar um one-liner usando awk / sed / grep / tr / cut / perl que pode alterar o valor de "enabled = 0" para "enabled = 1", mas SOMENTE para a categoria [shovel]?

    
por user1930831 27.01.2017 / 05:30

4 respostas

4

Em sed , você pode usar um intervalo (parar na linha vazia no final da categoria [shovel] ):

sed '/\[shovel\]/,/^$/ s/enabled = 0/enabled = 1/' file

a primeira parte /\[shovel\]/,/^$/ significa encontrar uma linha com [shovel] , continue até encontrar uma linha vazia e faça o (s) seguinte (s) comando (s) (neste caso, um simples s/old/new ) apenas nessa parte de file

Nota em resposta ao comentário: Até onde eu sei, sed não aceitará delimitadores alternativos em intervalos e endereços (portanto, escape de / caracteres que devem ser literais, se você precisar combiná-los), mas você ainda pode usar um em qualquer um dos seguintes comandos, por exemplo:

sed '/\[shovel\]/,/^$/ s|enabled = 0|enabled = 1|' file
    
por 27.01.2017 / 06:45
0

Aqui está uma solução usando o Perl, supondo que sua configuração esteja em config.ini :

perl -000 -n -i -e 's/^enabled = 0$/enabled = 1/m if /^\[shovel\]\n/; print;' config.ini

Isso faz o seguinte:

  • -000 - Lê o arquivo no modo de parágrafo, essencialmente o mesmo que fazer $/ = "\n\n"; no código.
  • -n - Executa o código especificado dentro de um loop while (<>) { } .
  • -i - Editar em linha o arquivo especificado em vez de imprimir na saída padrão. Opcionalmente, você pode especificar uma extensão, o que fará com que o arquivo de entrada seja submetido a backup com essa extensão. Por exemplo, -i.bak criaria um arquivo de backup chamado config.ini.bak .
  • -e - Executa o código perl especificado.

O próprio código diz para substituir linhas contendo exatamente enabled = 0 com enabled = 1 se a entrada "parágrafo" começar com [shovel] em uma linha sozinha. Os [ e ] precisam ser escapados, pois normalmente têm um significado especial em uma expressão regular.

    
por 27.01.2017 / 06:48
0

você pode tentar esta solução awk

awk '/shovel/{flag=1}flag&&/enabled/{$NF=1;flag=0}1' input
    
por 27.01.2017 / 07:13
0

Você pode restringir sed a apenas modificar uma linha específica:

 sed -i '3s/enabled = 0/enabled = 1/g' file

Isso só modificará a terceira linha para [roxo]

    
por 27.01.2017 / 08:17