Como repetir o valor da coluna se a célula da linha seguinte estiver vazia

0

Arquivo de entrada

CARD   SG   CLASS   ATT  
11      0   DAS     YES 
CARD   SG   CLASS   ATT
12      0   ECT     YES
CARD   SG   CLASS   ATT
13      0   VAS     YES
        1   DAS     NO
CARD   SG   CLASS   ATT
14      0   SAT     YES
CARD   SG   CLASS   ATT
15      0   CDT     YES
        1   VEG     YES
        2   GAT     NO

Esperar saída:

 CARD   SG   CLASS   ATT
 11     0   DAS      YES    
 12     0   ECT      YES
 13     0   VAS      YES
 13     1   DAS      NO
 14     0   SAT      YES
 15     0   CDT      YES
 15     1   VEG      YES
 15     2   GAT      NO

O que eu fiz:

awk ' /YES|NO/{VAL=$1};/ATT/{Print "CARD" "SG" "CLASS" "ATT" };/YES|NO/{ print VAL, $2, $3, $4} ' SCGR.txt  | column -t   

11  0    DAS  YES
12  0    ECT  YES
13  0    VAS  YES
1   DAS  NO
14  0    SAT  YES
15  0    CDT  YES
1   VEG  YES
2   GAT  NO

Por favor me ajude

    
por tek0078 24.09.2016 / 10:55

4 respostas

0

Depurando seu ligner - Vários problemas menores:

  • Print - print
  • /ATT/{Print "CARD" "SG" "CLASS" "ATT" } - /ATT/{print} ou /ATT/;
  • /YES|NO/{VAL=$1} também é trigerado nos registros de 3 campos, limpando o valor salvo anteriormente. (altere a ordem ou $4 ~ /YES|NO/ )

Uma variante:

awk 'NF==4{v=$1;print} NF==3{print v,$0}' 

removendo cabeçalhos extras e recuos:

awk '/^CARD/ && NR>1 { next } 
     NF==4           { v=$1;print } 
     NF==3           { print v,$0 }'
    
por 24.09.2016 / 12:01
1

Tente isto (assumindo que todas as linhas de cabeçalho são exatamente iguais):

awk '  NR==1{header=$0; count=NF; print; next}
       ($0~header) {next}
       (NF==count) {col1=$1}
       (NF<count)  {printf("%s",col1)}
       1 ' infile | column -t
    
por 24.09.2016 / 11:48
0

Se não nos importamos com o alinhamento de colunas e queremos apenas dados separados em branco normalizados, o padrão básico é:

awk -F' +' '{ $1 = ($1 ~ /^$/ ? prev : $1); prev = $1; print }'

Veja, se configurarmos um separador de campo personalizado que não seja igual ao espaço padrão, conseguiremos a verdadeira separação de campos. Se o registro começar com uma correspondência para o separador, um campo vazio será delimitado.

Por padrão, o Awk não se separa; tokenizes: extrai de cada tokens de registro que são sequências de um ou mais caracteres não-em branco / não-newline. Isso significa que espaços em branco iniciais / finais são ignorados. Portanto, se você tiver uma coluna ausente 1, o valor na coluna 2 se tornará a coluna 1.

Com nosso regex separador / +/ , obtemos um comportamento de separação real. Um registro com espaços iniciais e finais como 1 2 3 4 é tratado como <SEP>1<SEP>2<SEP>3<SEP>4<SEP> . Assim, existem seis campos: "" , "1" , ..., "4" , "" . Existe um campo antes do primeiro <SEP> e depois do último.

A propósito, se o primeiro registro pode ter um campo perdido, obviamente precisamos de um padrão para prev . Também não queremos que a lógica se aplique aos títulos. Também vamos substituir o operador ternário por um if : Assim:

awk 'BEGIN { FS = " +"; prev = 0 }
     NR == 1
     NR > 1 { if ($1 == "") $1 = prev
              print
              prev = $1 }'
FOO BAR BAZ
FOO BAR BAZ
  2 3 4
0 2 3 4
1 2 3 4
1 2 3 4
  2 3 4
1 2 3 4
    
por 24.09.2016 / 18:29
-1

Apenas para a decisão da sed sobre educação

sed '
    1b                             #output 1st line (header)
    $!N                            #add next line to operate 2 lines altogether
    s/\(.*\)\n\(CARD.*\)/\n/   #move line with CARD to first place 
    /^CARD/D                       #delete line with CARD and go to start
    s/^\(\([0-9]*\s*\).*\n\)\s\s*// 
                                   #repeat 1st field of 1st line if empty in 2nd
    /\n/{P;D}                      #print&remove 1st line, go to start 
    '
    
por 24.09.2016 / 16:19