Como passar variáveis para o comando awk com condições?

2

Eu tenho um loop while que lê dados de um arquivo com nomes de cidades:

city_name:

COIMBATORE
MADURAI
PONDICHERRY
SALEM
TRIPUR
TIRUCHI
TIRUNELVELI
TUTUCORIN
VELLORE

e usando um comando awk no loop while e tentando ler a variável definida em while loop body novamente na instrução awk , no entanto, isso não está funcionando e me dando erros. Eu entendo que awk requer que as variáveis sejam definidas para seu corpo separadamente para permitir que awk entenda o uso da variável e possa ler seu valor.

Meu loop while é como o seguinte:

while read city
do
        awk -F, '{
                        if ( $1 == "ACTIVE" ) &&
                        ( $2 == "$city" )
                        print $1
                }' siteDBName >> count

        SUM='awk '{ sum += $1 } END { print sum }' count'

done < city_name

em que o arquivo siteDBName contém várias colunas com dados como os seguintes:

siteDBName:

ACTIVE,COIMBATORE,MGT500,1,5,7....
INACTIVE,MADURAI,GT500,5,6,7...
ACTIVE,SALEM,TR600,6,4,6...
ACTIVE,COIMBATORE,GT500,4,5,6...
..
..

Aqui, eu tentei usar o awk -v c=$city junto com o resto das declarações, mas isso também me deu erros.

Como posso usar a variável usada e inicializada no loop while dentro da instrução awk dentro deste loop while?

    
por Ankit Vashistha 28.07.2015 / 07:55

3 respostas

2

Assim como @cuonglm e @YoMismo afirmaram, você está usando a variável errada e o caminho errado para referenciá-la. Deve ser algo como:

while read city
do
        awk -v c="$city" -F, '{
                        if ( $1 == "ACTIVE"  && $2 == c )
                        print $1
                }' siteDBName >> count
        SUM='awk '{ sum += $1 } END { print sum }' count'

done < city_name
    
por 28.07.2015 / 09:14
2

Você tem duas opções básicas: i) usar -v para passar a variável para awk ou ii) fechar o script ' em torno do awk , usar a variável shell e continuar o ' novamente.

  1. Use -v

    while read city
    do
        awk -vcity="$city" -F, '{
                                  if ( $1 == "ACTIVE"  && $2 == city ){print $1}
                                 }' siteDBName >> count
    done < city_name
    
  2. Feche a cotação

    while read city
    do
        awk  -F, '{
                     if ( $1 == "ACTIVE"  && $2 == "'$city'" ){print $1}
                  }' siteDBName >> count
    done < city_name
    

Eu removi a linha SUM= porque ela não estava fazendo nada útil, já que $1 é ACTIVE , então adicionar isso não faz sentido. Veja minha abordagem alternativa abaixo para uma maneira de fazer isso corretamente.

Além disso, observe que com essa abordagem, você precisa ler o arquivo siteDBName várias vezes. Uma versão mais eficiente seria:

$ awk -F, '{
             if(NR==FNR){cities[$1]++;}
             else if($1=="ACTIVE" && $2 in cities ){sum++}
            } END{print sum,"active cities"}' city_name siteDBName 
3 active cities
    
por 28.07.2015 / 09:43
1

Se você está interessado apenas em SUM

grep -cf <(sed s/^/\^ACTIVE,/ city_name) siteDBName

ou para arquivos grandes

grep -f city_name siteDBName | grep -c ^ACTIVE
    
por 28.07.2015 / 10:11