Definindo uma variável no awk

1

Eu tenho um arquivo de entrada assim:

3.59717487E+05  3.40210880E+06        4075.32   7066.00   4075.32 7066      4075.322 2 a_final_psdm_LY1-1250_20160307             
3.59725248E+05  3.40211860E+06        4063.53   7067.00   4063.53 7067      4063.527 2 a_final_psdm_LY1-1250_20160307             
3.59733009E+05  3.40212840E+06        4051.73   7068.00   4051.73 7068      4051.731 2 a_final_psdm_LY1-1250_20160307             
3.59740771E+05  3.40213820E+06        4039.94   7069.00   4039.94 7069      4039.936 2 a_final_psdm_LY1-1250_20160307   

Eu preciso pegar a última coluna e definir uma variável que seja apenas a parte LY1-1250. Isso é o que eu tenho até agora:

awk ' 
BEGIN{

     if($NF !~ /LY1/){
       print
     }
     else{

        tag=$NF
        print tag
     }
 }

mas isso me dá tag = a_final_psdm_LY1-1250_20160307

Eu preciso de tag = LY1-1250

Em um script de shell, eu apenas faria

tag='echo $NF | sed ... blah blah

mas no awk não parece avaliar a expressão.

    
por jaffa1201 21.04.2016 / 11:56

3 respostas

1

Como a "tag" é a parte depois do penultimate _ , você pode simplesmente usar isso como um separador de campo:

$ awk -F_ '{if($(NF-1)~/LY1/){print $(NF-1)}else{print}}' file
LY1-1250
LY1-1250
LY1-1250
LY1-1250

Ou, para usá-lo como uma variável:

awk -F_ '{if($(NF-1)~/LY1/){tag=$(NF-1); print tag}else{print}}' file

Eu não entendo por que você tinha seu código em um bloco BEGIN{} , que seria executado apenas uma vez e antes de qualquer linha ser lida, então NF não seria definido.

De qualquer forma, para o caso geral, a maneira de salvar uma substring em uma variável no awk é usar substr ou sub . Então, você também poderia ter feito algo como:

$ awk '{ 
        if($NF~/LY1/){
            tag=$NF; 
            sub(/.*LY1/,"LY1",tag); 
            sub(/_[^_]*$/,"",tag); 
            print tag
        }
        else{ print } }' file
LY1-1250
LY1-1250
LY1-1250
LY1-1250
    
por 21.04.2016 / 12:24
1

Acho que você pode ter entendido mal as condicionais de awk . O começo de cada linha é a condição. Esta é uma maneira mais ... awk -ward de fazê-lo: E sobre

awk '
/LY1/ { 
        tag=gensub(/_.*/,"","1",gensub(/.*LY1/,"LY1","1", $NF))
        print tag
        next
}
{
    print
}' input.file

O primeiro /LY1/ é uma matches -condição implícita - só executa a expressão se a linha de entrada corresponder a essa expressão regular. A expressão começa com a substituição de tudo nessa linha, até, e inclusive, LY1 with LY1 e coloca isso na tag de variável. Em seguida, imprime a tag e a next -statement ignora todas as outras expressões para este registro .

Depois disso vem uma expressão incondicional, que apenas imprime a linha como está - mas isso não será executado se a expressão anterior foi executada, já que isso teria chamado next .

    
por 21.04.2016 / 12:39
1

Faça uma tentativa para isso:

awk '
{
   if(!match($NF,"LY1[^_]*")){
     print
   }
   else {
     tag=substr($NF,RSTART,RLENGTH)
     print tag
   }
}' input.file

match() encontra a expressão regular.

Esta função também está definindo duas variáveis especiais RSTART e RLENGTH que indicam onde a expressão regular começa e termina.

    
por 21.04.2016 / 12:16

Tags