Extraindo dados com awk quando algumas linhas possuem valores vazios / ausentes

5

Eu tenho uma amostra como mostrado aqui:

input.txt

   USERS        position   ref   rslt   
    usr1                    X     B   
    usr2          2980            C   
    usr3          3323      P      
    usr4                          A  
    usr5          5251      U      
    usr6          9990            A
    usr7          10345     T     

Eu preciso imprimir a coluna "rslt" e os "USERS" correspondentes, o arquivo de saída deve ser assim:

output.txt

  USERS     rslt   
   usr1       B   
   usr2       C       
   usr4       A
   usr6       A 

Eu tentei usar o comando awk , mas não funcionou. Note que, toda a posição preta da tabela é preenchida com espaços (o número de espaços é diferente em cada linha)

    
por Mishkat Hasan 07.11.2016 / 08:57

3 respostas

11

Nesse caso, uma solução possível é fornecer as larguras dos campos na seção inicial:

awk 'BEGIN {FIELDWIDTHS = "16 11 6 7"} 
    $4 ~/[^ ]/ {print $1 $4}' 

As larguras de campo podem ser contadas manualmente, mas para cabeçalhos complexos eu gosto de começar com

 head -1 f | grep -Po '.*? (?=\S|$)' | awk '{print length}'

UPDATE: ... ou para lidar com espaços iniciais e finais no cabeçalho:

 head -1 f | grep -Po '(^ *|\S).*?( (?=\S)|$)' | awk '{print length}'
    
por 07.11.2016 / 09:23
6

O comando awk não é a ferramenta mais apropriada para este trabalho. Use cut , o que leva como um argumento as posições dos caracteres dos campos que você quer extrair. Então, no seu exemplo, especifique que USERS começa na posição de caractere 1 e termina na posição de caractere 8 e rslt começa na posição de caractere 33.

$ cut -c 1-8,33- input.txt
   USERS rslt
    usr1  B
    usr2  C
    usr3
    usr4  A
    usr5
    usr6  A
    usr7

Veja o seguinte sobre como contar as posições dos personagens.

         1         2         3         
123456789012345678901234567890123456789
   USERS        position   ref   rslt   
    usr1                    X     B   
    usr2          2980            C   
    usr3          3323      P      
    usr4                          A  
    usr5          5251      U      
    usr6          9990            A
    usr7          10345     T      
    
por 07.11.2016 / 12:27
1

Você pode obter quase usando o utilitário unexpand para 'tabify' a entrada, depois definindo o separador de campo awk para a guia e apenas imprimindo linhas cujo campo final consiste em algo diferente do que espaços:

unexpand -t8 input.txt | awk -F'\t' '$NF ~ /[^ ]/ {print $1, $NF}'
    usr1   B
    usr2   C
    usr4   A
    usr6   A

Não funciona para a linha de cabeçalho porque há menos espaços entre os campos position e ref . Se o cabeçalho é um deve ter, você poderia lidar com isso separadamente:

unexpand -t8 input.txt | awk -F'\t' 'NR == 1 {print $1,$3} $NF ~ /[^ ]/ {print $1, $NF}'
    
por 07.11.2016 / 18:11