Perl / awk / bash: multiplica e soma valores colocando valores inline em vez do texto original [closed]

0

Eu tenho um texto assim:

;---------------------------------------
JOURNEY_ARRAY_01
    .BYTE <JOURNEY_00
    .BYTE <JOURNEY_01
;---------------------------------------
JOURNEY_ARRAY_03
    .BYTE JOURNEY_01-JOURNEY_00
    .BYTE JOURNEY_02-JOURNEY_01
;---------------------------------------
JOURNEY_00                              ; From 00 to 01
    .BYTE $01, $01, $01, $03, $01, $01, $03, $01
    .BYTE $03, $01, $03, $01, $03, $01, $03, $01
    .BYTE $03, $03, $01, $03, $03, $03, $03, $00
    .BYTE $03, $03, $00, $03, $00, $03, $00, $03
    .BYTE $00, $03, $00, $03, $03, $00, $03, $03
    .BYTE $00, $03, $03, $03, $03, $03, $03, $01
    .BYTE $03, $03, $01, $03, $03, $01, $03
;---------------------------------------
JOURNEY_01                              ; From 00 to 04
    .BYTE $01, $01, $01, $03, $01, $01, $03, $01
    .BYTE $03, $01, $03, $01, $03, $01, $03, $01
    .BYTE $03, $03, $01, $03, $01, $03, $01, $01
    .BYTE $03, $01, $03, $01, $01, $01, $01, $01
    .BYTE $02, $01, $01, $01, $02, $01, $01, $01
    .BYTE $02, $01, $01, $01, $01, $01, $01, $01
    .BYTE $01, $01, $01
;---------------------------------------

Eu preciso pegar cada valor numérico depois de ".BYTE" e para cada 4 valores fazer isso:  - primeiro valor não faz nada;  - segundo valor multiplique * 4;  - terceiro valor multiplicar * 16;  - quarto valor multiplicar * 64; some estes 4 valores e coloque o resultado, no formato hexadecimal prefixado com "$" em vez dos quatro valores originais. Se os valores após ".BYTE" não forem multiplos de 4 ou forem menores que 4, os valores omissos deverão ser calculados como zeros. Por exemplo:

.BYTE $01, $01, $01, $03, $01, $01, $03, $01

deve se tornar:

.BYTE $57, 5D

porque:

03*1 = 3 +
01*4 = 4 +
01*16 = 16 +
01*64 = 64 = 87 = $57
and
01*1 = 1 +
03*4 = 12 +
01*16 = 16 +
01*64 = 64 = 93 = $5D

Valores não apresentados devem ser calculados como zero nas matemáticas ... Obviamente, outro texto não deve ser alterado.

Qualquer um?

    
por Flavio Pasqualin 21.10.2014 / 11:57

1 resposta

1

A solução sed plus gawk (GNU awk) a seguir executa a tarefa solicitada:

 sed -e '/ .BYTE/{s/\$/0x/g;s/,//g}' INPUTFILE.txt | 
     gawk --non-decimal-data '/.BYTE.*0x/{ printf ".BYTE $%x, $%x\n",
       ($5+$4*4+$3*16+$2*64 ) , ($9+$8*4+$7*16+$6*64) };!/.BYTE.*0x/{print}'

A chamada sed substitui $01 por 0x01 e exclui vírgulas nas linhas .BYTE que precisam ser modificadas. A chamada awk reconhece os números hexadecimais, executa os cálculos e gera o resultado para essas linhas. Outras linhas são simplesmente copiadas para a saída.

O padrão funciona para o exemplo dado, mas pode precisar ser modificado se houver outros formatos de linha .BYTE usados.

O comando assume que há exatamente dois blocos de 4 números em cada linha. Então sai para a última linha da entrada

.BYTE $54, $0
    
por 21.10.2014 / 12:38

Tags