Script para vários campos numéricos

2

Eu tenho um arquivo grande com um monte de texto diferente. Eu quero usar um script que irá percorrer todo o arquivo e vários o número por um valor predeterminado, neste exemplo 2 no campo de número EXP="XYZ". No entanto, só deve fazer isso se VIEW_RANGE, COOLEYE e TAMEBLE estiverem antes. O arquivo todo é também um forro inteiro.

Exemplo

TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="12000"
TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="1000"

Deve acabar parecendo

TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="24000"
TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="2000"

Como posso conseguir isso?

    
por Rarara221 19.07.2016 / 01:48

1 resposta

2

Vamos considerar este arquivo de teste:

$ cat file
TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="12000" other stuff EXP="2" TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="1000"

Para duplicar os valores de EXP, mas apenas se precedido por TAMEBLE, COOLEYE e VIEW_RANGE:

$ awk -F'[="]+' '$1=="TAMEBLE" {a[NR]=1} $1=="COOLEYE"{b[NR]=1} $1=="VIEW_RANGE" {c[NR]=1} $1=="EXP" && a[NR-3] && b[NR-2] && c[NR-1] {$0= $1 "=\"" (2*$2) "\""} END{printf"\n"} 1' RS=' ' ORS=' ' file
TAMEBLE="0" COOLEYE="20" VIEW_RANGE="9" EXP="24000" other stuff EXP="2" TAMEBLE="0" COOLEYE="5" VIEW_RANGE="12" EXP="2000" 

Ou, se você preferir o código distribuído em várias linhas:

awk -F'[="]+' '
    $1=="TAMEBLE" {
        a[NR]=1
    }

    $1=="COOLEYE"{
        b[NR]=1
    } 

    $1=="VIEW_RANGE" {
        c[NR]=1
    } 

    $1=="EXP" && a[NR-3] && b[NR-2] && c[NR-1] {
        $0= $1 "=\"" (2*$2) "\""
    } 

    END{printf"\n"}

    1
    ' RS=' ' ORS=' ' file

Como funciona

  • -F'[="]+'

    Isso define o separador de campo para qualquer combinação de = ou " .

  • $1=="TAMEBLE" {a[NR]=1}

    Se o primeiro campo desse registro for TAMEBLE, defina a[NR] como true, em que NR é o número do registro.

  • $1=="COOLEYE"{b[NR]=1}

    Da mesma forma, se o primeiro campo desse registro for COOLEYE, defina b[NR] como true.

  • $1=="VIEW_RANGE" {c[NR]=1}

    Da mesma forma, se o primeiro campo desse registro for VIEW_RANGE, defina c [NR] 'como verdadeiro.

  • $1=="EXP" && a[NR-3] && b[NR-2] && c[NR-1] {$0= $1 "=\"" (2*$2) "\""}

    Se esse registro tiver um primeiro campo de EXP e os primeiros campos dos registros anteriores estiverem na ordem exigida, duplique o valor de EXP .

  • END{printf"\n"}

    Depois de terminar de ler o arquivo, imprima uma nova linha para finalizar corretamente a linha.

  • 1

    Esta abreviada enigmática do awk para imprimir a linha.

  • RS=' ' ORS=' '

    Isto diz ao awk para tratar um espaço em branco como o separador de registro na entrada e na saída.

por 19.07.2016 / 02:40