Usando o gawk para alterar colunas após um identificador de linha

0

Eu tenho vários arquivos de desenho no formato detalhado abaixo. Eu preciso aumentar o valor de um número na área do arquivo abaixo após a linha BO . Todos os valores (na amostra abaixo) que são 14,00 precisam ser aumentados em 1 a 15,00. Neste caso, as 5 linhas abaixo de BO se tornariam 15,00. Eu posso ver que $4+1 aumentará o valor, no entanto, as duas casas decimais estão faltando.

Eu posso ver que o gawk permite expressões como C, então seria uma solução. O que não consigo entender é como detectar o registro BO e manipular os campos até que EN seja atingido.

Qualquer conselho sobre como isso pode ser alcançado é apreciado.

Obrigado.

AK
  v       0.00u      0.00       0.00       0.00       0.00       0.00       0.00
        398.56       0.00       0.00       0.00       0.00       0.00       0.00
        398.56      50.00       0.00       0.00       0.00       0.00       0.00
          0.00      50.00       0.00       0.00       0.00       0.00       0.00
          0.00       0.00       0.00       0.00       0.00       0.00       0.00
BO
  v      25.00o     18.75      14.00
  v      75.00o     18.75      14.00
  v     323.56o     18.75      14.00
  v     373.56o     18.75      14.00
EN
    
por 2CV375 25.08.2017 / 17:22

1 resposta

0

Isto pode ser conseguido através do uso de uma máquina de estados muito simples:

$ awk -v OFS="\t" '/^[A-Z][A-Z]/ && !/^BO/ { flag=0 } /^BO/ { flag=1 } flag == 1 && NF == 4 { $4 = sprintf("%.2f", 1+$4) } { print }' file
AK
  v       0.00u      0.00       0.00       0.00       0.00       0.00       0.00
        398.56       0.00       0.00       0.00       0.00       0.00       0.00
        398.56      50.00       0.00       0.00       0.00       0.00       0.00
          0.00      50.00       0.00       0.00       0.00       0.00       0.00
          0.00       0.00       0.00       0.00       0.00       0.00       0.00
BO
v       25.00o  18.75   15.00
v       75.00o  18.75   15.00
v       323.56o 18.75   15.00
v       373.56o 18.75   15.00
EN

O script não faz nada além de passar a entrada para a saída até atingir a linha que começa com BO , então define flag para 1.

Se flag for 1 e a linha atual contiver quatro colunas, a quarta coluna será reformatada usando sprintf() e 1+$4 . A especificação de formato %.2f significa "um valor de ponto flutuante com duas casas decimais".

Se algo diferente de BO for encontrado no início da linha, flag será redefinido para zero.

O preenchimento entre as colunas é alterado nas linhas de saída onde uma modificação foi feita. Isso ocorre porque awk divide os campos em espaços em branco e depois os reúne usando OFS (definido como um caractere de tabulação aqui) quando a saída acontece.

Para obter exatamente o mesmo formato de saída da entrada, você pode fazer algo como

$ awk -v OFS="\t" '/^[A-Z][A-Z]/ && !/^BO/ { flag=0 } /^BO/ { flag=1 } flag == 1 && NF == 4 { printf("%3s %11s%10.2f %10.2f\n", $1,$2,$3,1+$4); next } { print }' file
AK
  v       0.00u      0.00       0.00       0.00       0.00       0.00       0.00
        398.56       0.00       0.00       0.00       0.00       0.00       0.00
        398.56      50.00       0.00       0.00       0.00       0.00       0.00
          0.00      50.00       0.00       0.00       0.00       0.00       0.00
          0.00       0.00       0.00       0.00       0.00       0.00       0.00
BO
  v      25.00o     18.75      15.00
  v      75.00o     18.75      15.00
  v     323.56o     18.75      15.00
  v     373.56o     18.75      15.00
EN
    
por 25.08.2017 / 17:33

Tags