verificar dados em colunas quando um dado ou algum pode estar faltando ou presente?

3

Não tenho certeza se isso é possível.

digamos que eu tenha colunas como:

Team      Colour      Game      Rainfall      PlayerName  
XYZ       Blue        Cricket   Yes           Kapil

suponha que eu precise procurar por qualquer dado que esteja abaixo de Game i possa fazer isso usando o awk algo como:

  awk '{for(i=1;i<NF;i++)
        {
         if($i == "Game")
          {
          GameData=i
          next
          }
        if( i == GameData )
          {
          print "Column below Game is" $i
          }
        }
      }'

mas e se eu não tiver certeza de que o valor em algumas colunas pode estar faltando como qualquer um dos

XYZ       Blue     

pode estar faltando ou ambos podem estar ausentes ou presentes.

EDITAR : Vamos dizer que a primeira letra T da equipe (primeira coluna) está sempre no começo e primeira letra C de Cor é sempre depois de 10 caracteres desde o início, a primeira letra G do Jogo é sempre depois de 20 caracteres do começo e assim por diante.

    
por munish 11.05.2013 / 17:07

3 respostas

4

Eu não sei se há realmente uma boa maneira de recuperar essas informações, se os campos no meio estão em branco e você permite que o delimitador vá em uma quantidade não especificada de caracteres, como você poderia dizer que o campo que você acabar vendo é Colour e não PlayerName ?

Em algum momento, os dados precisam ser formatados de forma que possam ser analisados de forma programática e qualquer outra coisa seja apenas o resultado de feeds de dados ruins. Você precisa mudar para um único delimitador de caractere se quiser deixar campos aleatórios fora.

Se for uma questão de legibilidade, você pode roteirizar com segurança uma apresentação dos dados em que os campos são preenchidos com espaços em branco até ficarem sob as colunas apropriadas, mas isso destrói as informações avisará em qual campo você está realmente olhando, por isso é um processo unidirecional.

    
por 11.05.2013 / 17:12
3
awk -v field="Game" -v FIELDWIDTHS="10 12 10 13 25" '
  NR == 1 {cmpstr="^" field " *$";
    for (i=0;i<6;i++) if ($i ~ cmpstr) { fieldindex=i; next;}; exit 1};
  {gsub(" ","",$fieldindex); if ($fieldindex != "") print $fieldindex;}' inputfile

Editar 1: Saia com o código de erro se não for encontrada uma coluna correspondente.

Editar 2: Não produza linhas vazias.

    
por 11.05.2013 / 18:28
3

Você pode usar FIELDWIDTHS , embora essa seja uma extensão gawk e não tão portátil. Você também pode nomear campos como, por exemplo:

awk '
BEGIN {
    FIELDWIDTHS = "10 9 13 11 32"
    team=1; colour=2; game=3; rainfall=4; name=5;
}

NR == 1 {
    next
}
/./ {
    print $3, $name
} ' fixwdata

As larguras em FIELDWIDTHS são compostas da seguinte forma:

  Team      Colour   Game      Rainfall   PlayerName  
  XYZ       Blue     Cricket   Yes        Kapil
# <-  10  -><-  9  -><-  10  -><-  11   -><-     NN      ->  FIELDWIDTHS
#     $1        $2       $3        $4            $5          Field numbers

Opcionalmente, você pode usar, por exemplo, substr () . Se a primeira linha contiver nomes exclusivos onde não há repetição, ou seja, não Name , TeamName , você poderia usar index() .

Isso parece um pouco frágil. Se os dados tiverem largura fixa, você poderá codificar isso, mas alguns programas também expelem a largura fixa - , mas também alinham os dados de acordo a largura dos dados. Então você pode obter:

Output1:

FLD1 FLD2
foo  bar

Output2:

FLD1   FLD2
foobaz bar

Este exemplo não apresenta repetição de nomes em outros nomes:

awk '
function get_fld(fld_name)
{
    return substr($0, col[fld_name"s"], col[fld_name"w"]);
}
BEGIN {
    team=1
    colour=2
    game=3
    rainfall=4
    name=5
}
NR == 1 {
    col["1s"]=0
    col["2s"]=index($0, $2)
    col["3s"]=index($0, $3)
    col["4s"]=index($0, $4)
    col["5s"]=index($0, $5)
    col["1w"]=col["2s"] - 1
    col["2w"]=col["3s"] - col["2s"]
    col["3w"]=col["4s"] - col["3s"]
    col["4w"]=col["5s"] - col["4s"]
    col["5w"]=22
    next
}
/./ {
    printf(\
    "%-5s {\n"\
    "%12s: %s\n"\
    "%12s: %s\n"\
    "%12s: %s\n"\
    "%12s: %s\n"\
    "}\n",
    get_fld(name),
    "Team", get_fld(team),
    "Colour", get_fld(colour),
    "Game", get_fld(game),
    "Rainfall", get_fld(rainfall));
} ' fixwdata

Entrada:

Team      Colour   Game         Rainfall   PlayerName  
ABC       Blue     Cricket      Yes        Kapil
DEF       Red      Cricket                 Konos
DEF       Yellow   Go                      Kripl
DUX       Black
Zon       Purple   Golf         No         Gim
Zon       Purple   Golf         No         Jom

Saída:

Kapil {
        Team: ABC       
      Colour: Blue     
        Game: Cricket      
    Rainfall: Yes        
}
Konos {
        Team: DEF       
      Colour: Red      
        Game: Cricket      
    Rainfall:            
}
Kripl {
        Team: DEF       
      Colour: Yellow   
        Game: Go           
    Rainfall:            
}
      {
        Team: DUX       
      Colour: Black
        Game: 
    Rainfall: 
}
Gim   {
        Team: Zon       
      Colour: Purple   
        Game: Golf         
    Rainfall: No         
}
Jom   {
        Team: Zon       
      Colour: Purple   
        Game: Golf         
    Rainfall: No         
}
    
por 11.05.2013 / 18:43