Como posso listar o segundo para a última palavra encontrada em uma seqüência de instruções no awk

1

Meu arquivo está escrito como:

apples,oranges,berries,cherries

beer,wine,shots

chocolate,icecream,cake,muffins

cherries,guacamole,lychee

Eu preciso produzir a segunda para a última palavra em linhas que contenham a palavra cerejas usando awk:

    I want it to print:

comida: bagas, guacamole

cerejas apareceu: 0/2 vezes

Atualmente tenho:

/cherries/

BEGIN {print "food:";}

{for (NR in a) {

FS=",";

printf($(NF-1));j++;

if((NF-1)=="cherries"){$i++;}

}

}
END {print "cherries appeared" i/j "times"}

O que acontece é que ele imprime todas as linhas que contêm cerejas (a linha inteira) e $ i $ sai com um valor de 0, então aqui seria impresso:

comida: maçãs, laranjas, bagas, cherriescherries, guacamole, lichia

cerejas apareceu: nantimes

    
por WaffleMonster 28.02.2014 / 17:49

4 respostas

1

awk -F, 'BEGIN {printf "%s","food: ";}; '\
'/cherries/ {if (matches>0) printf "%s",", "; printf "%s",$(NF-1); matches++;};'\
' END {print "";print "cherries appeared " matches "/" NR " times"}'

leva a essa saída:

food: berries, guacamole
cherries appeared 2/4 times
    
por 28.02.2014 / 17:57
1

Você quer contar o número de vezes ou o número de linhas em que as cerejas apareceram?

awk -F, '$0~k{s=s (s?", ":x) $(NF-1); t+=gsub(k,x)}
         END{printf "food: %s\n%s appeared %d/%d times\n", s, k, t, NR}
        ' k=cherries file

ou

awk -F, '$0~k{s=s (s?", ":x) $(NF-1); t++}
         END{printf "food: %s\n%s appeared in %d/%d lines\n", s, k, t, NR}
        ' k=cherries file
    
por 01.03.2014 / 22:30
0

Eu acho que o que você quer é

$ awk -F, 'BEGIN{ORS=",";printf "food: "} 
          /cherries/{print $(NF-1); matches++;}; 
          END{printf "\ncherries appeared "matches "/" NR " times\n"}' file 
food: berries,guacamole,
cherries appeared 2/7 times

Note que o seu arquivo tem espaço duplo, então o número de linhas inclui as linhas em branco. Para evitar isso, use

$ awk -F, 'BEGIN{ORS=",";printf "food: "} 
           /./{k++} 
           /cherries/{print $(NF-1); matches++;};
          END{printf "\ncherries appeared matches /" k " times\n"}' file
food: berries,guacamole,
cherries appeared matches /4 times

-F "," é equivalente a FS="," . ORS é o separador de registro de saída que também é definido como , para facilitar a impressão. A desvantagem é que ele adiciona um , extra no final da linha food: , mas você pode removê-lo passando por | sed 's/,$//' . Seu principal problema foi que a impressão do awk imprime tudo o que você der, seguido pelo valor de ORS , que é uma nova linha por padrão.

Eu não entendo o que você quer dizer com cherries sendo o penúltimo campo, já que esse nunca é o caso em seu exemplo.

    
por 28.02.2014 / 19:01
0

Outra maneira:

awk -F, 'BEGIN{printf "food: "}
         /cherries/ {printf $(NF-1) FS; count++}
         END{printf "\ncherries appeared %d/%d times\n", count, NR}' file
  • BEGIN imprime o cabeçalho do texto.
  • /cherries/ {printf $(NF-1) FS; count++} continua imprimindo a segunda última palavra nas linhas que contêm cherries . Nesse caso, também acompanha quantas linhas correspondem.
  • END imprime o resumo.

Para o seu arquivo, ele retorna:

$ awk -F, 'BEGIN{printf "food: "} /cherries/ {printf $(NF-1) FS; count++} END{printf "\ncherries appeared %d/%d times\n", count, NR}' file
food: berries,guacamole,
cherries appeared 2/4 times
    
por 02.03.2014 / 00:45

Tags