Conte o número de ocorrências de um número específico antes de cada string no linux

0

Eu tenho este arquivo:

90  1 
120 1
Transition  
150 1
Transition  
165 1
Transition  
180 1
225 1
240 1
255 1
270 1
Transition  
285 1
Transition  

e eu quero essa saída:

1   2
2   1
3   1
4   5
5   1

Isso significa que 1 na segunda coluna vem 2 vezes antes da primeira transição. Como posso fazer isso usando o awk / grep?

    
por Dani 01.07.2016 / 13:45

3 respostas

4

Se você quiser contar o número de vezes que 1 está no segundo campo antes / entre cada linha que diz Transition , você pode usar awk like

awk '$2 == "1" {count++;} /Transition/ {t_count++; print t_count "\t" count; count=0;}' <input file>

que incrementará um contador sempre que 1 estiver no campo 2 e sempre que a linha corresponder a Transition imprimirá a contagem do número de linhas de Transição seguido pela contagem de 1 linhas.

Minha saída do seu arquivo de entrada:

1       2
2       1
3       1
4       5
5       1
    
por 01.07.2016 / 13:56
1

Aqui está uma solução Perl usando a mesma abordagem da resposta de Eric Renouf :

$ perl -lane '$F[1]==1 && $c++; if(/Transition/){$k++; print "$k\t$c"; $c=0}' file
1   2
2   1
3   1
4   5
5   1

Explicação

  • -l adiciona uma nova linha a cada print chamada;
  • -a habilita o "modo awk", dividindo cada linha de entrada na matriz @F , de forma que $F[0] seja o primeiro campo e $F[1] o segundo.
  • -ne diz a perl para processar seu arquivo de entrada linha a linha e aplicar o script dado por -e a cada linha.
  • $F[1]==1 && $c++; : increment $c por 1 se o segundo campo for 1 .
  • if(/Transition/){$k++; print "$k\t$c"; $c=0}' : se esta linha corresponder a Transition , incrementar $k em um, imprimir os valores atuais de $k e $c e definir $c de volta para 0.
por 01.07.2016 / 14:18
0

Existem outras linhas além de "Transição" e "número seguido por 1"? Eu suponho que não. O que acontece quando há duas transições sem nada entre elas? Eu suponho que isso não vai acontecer.

Você solicita especificamente o awk, e a resposta do Eric é perfeita. Para completar, eu gostaria de enviar uma versão sem o awk:)

| sed 's/.* 1 *$/CountThisLine/' | uniq -c | sed -n 's/CountThisLine//p' | nl -nln

O primeiro sed seleciona as linhas que você deseja contar e as torna idênticas, enquanto mantém as transições, o uniq -c conta linhas sequenciais idênticas, o segundo sed mantém apenas linhas não de transição e nl numera o resultado.

$ cat test.txt \
  | sed 's/.* 1 *$/CountThisLine/' \
  | uniq -c \
  | sed -n 's/CountThisLine//p' \
  | nl -nln
1             2 
2             1 
3             1 
4             5 
5             1 
    
por 01.07.2016 / 14:21