Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

216
Visualizações
Numeric expression in if condition of awk

Pretty new to AWK programming. I have a file1 with entries as:

15>000000513609200>000000513609200>B>I>0011>>238/PLMN/000100>File Ef141109.txt>0100-75607-16156-14 09-11-2014
15>000000513609200>000000513609200>B>I>0011>Danske Politi>238/PLMN/000200>>0100-75607-16156-14 09-11-2014
15>000050354428060>000050354428060>B>I>0011>Danske Politi>238/PLMN/000200>>4100-75607-01302-14 31-10-2014

I want to write a awk script, where if 2nd field subtracted from 3rd field is a 0, then it prints field 2. Else if the (difference > 0), then it prints all intermediate digits incremented by 1 starting from 2nd field ending at 3rd field. There will be no scenario where 3rd field is less than 2nd. So ignoring that condition.

I was doing something as:

 awk 'NR > 2 { print p } { p = $0 }' file1 | awk -F">" '{if ($($3 - $2) == 0) print $2; else l = $($3 - $2); for(i=0;i<l;i++) print $2++; }'

(( Someone told me awk is close to C in terms of syntax ))

But from the output it looks to me that the String to numeric or numeric to string conversions are not taking place at right place at right time. Shouldn't it be taken care by AWK automatically ?

The OUTPUT that I get:

513609200
513609201
513609200

Which is not quiet as expected. One evident issue is its ignoring the preceding 0s.

Kindly help me modify the AWK script to get the desired result.

NOTE:

awk 'NR > 2 { print p } { p = $0 }' file1 is just to remove the 1st and last entry in my original file1. So the part that needs to be fixed is:

awk -F">" '{if ($($3 - $2) == 0) print $2; else l = $($3 - $2); for(i=0;i<l;i++) print $2++; }'
over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

In awk, think of $ as an operator to retrieve the value of the named field number ($0 being a special case)

  • $1 is the value of field 1
  • $NF is the value of the field given in the NF variable

So, $($3 - $2) will try to get the value of the field number given by the expression ($3 - $2).

You need fewer $ signs

awk -F">" '{
    if ($3 == $2) 
        print $2
    else {
        v=$2
        while (v < $3) 
            print v++
    }
}'
over 4 years ago · Santiago Trujillo Relatório

0

Normally, this will work, but your numbers are beyond awk integer bounds so you need another solution to handle them. I'm posting this to initiate other solutions and better illustrate your specifications.

$ awk -F'>' '{for(i=$2;i<=$3;i++) print i}' file

note that this will skip the rows that you say impossible to happen

A small scale example

$ cat file_0
x>1000>1000>etc
x>2000>2003>etc
x>3000>2999>etc

$ awk -F'>' '{for(i=$2;i<=$3;i++) print i}' file_0
1000
2000
2001
2002
2003

Apparently, newer versions of gawk has --bignum options for arbitrary precision integers, if you have a compatible version that may solve your problem but I don't have access to verify.

over 4 years ago · Santiago Trujillo Relatório

0

For anyone who does not have ready access to gawk with bigint support, it may be simpler to consider other options if some kind of "big integer" support is required. Since ruby has an awk-like mode of operation, let's consider ruby here.

To get started, there are just four things to remember:

  1. invoke ruby with the -n and -a options (-n for the awk-like loop; -a for automatic parsing of lines into fields ($F[i]));
  2. awk's $n becomes $F[n-1];
  3. explicit conversion of numeric strings to integers is required;
  4. To specify the lines to be executed on the command line, use the '-e TEXT' option.

Thus a direct translation of:

awk -F'>' '{for(i=$2;i<=$3;i++) print i}' file

would be:

ruby -an -F'>' -e '($F[1].to_i .. $F[2].to_i).each {|i| puts i }' file

To guard against empty lines, the following script would be slightly better:

($F[1].to_i .. $F[2].to_i).each {|i| puts i } if $F.length > 2

This could be called as above, or if the script is in a file (say script.rb) using the incantation:

ruby -an -F'>' script.rb file

Given the OP input data, the output is:

513609200
513609200
50354428060

The left-padding can be accomplished in several ways -- see for example this SO page.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda