Grep um intervalo de valores com caracteres iniciais específicos

0

Eu tenho arquivos de 10 GB nos quais quero contar a ocorrência de algum texto específico, por exemplo, TY [0-9].

O formato do arquivo é como:

ABC,2A,2018-07-06,2018-06-20 00:00:00
BCD,TY1,2018-07-06,2018-06-20 00:00:00
EFG,TY2,2018-07-06,2018-06-20 00:00:00
IGH,2A,2018-07-06,2018-06-20 00:00:00

Quero obter a contagem de todo o texto que começa com TY . Eu tentei usar o egrep, mas não consigo entender isso.

egrep  "^TY[0-9]" Filename
    
por Developer 21.06.2018 / 20:37

3 respostas

3

Usando awk para contar o número de vezes que o segundo campo delimitado por vírgula no arquivo começa com a string TY seguida por um dígito:

awk -F, '$2 ~ /^TY[[:digit:]]/ { n++ } END { print n }' filename

Gostaria de saber se usar cut em combinação com grep seria rápido? Cortar a segunda coluna daria grep a menos de dados para trabalhar e, portanto, pode ser mais rápido do que apenas grep .

cut -d, -f2 filename | grep -c '^TY[[:digit:]]'

... mas não tenho certeza.

Após alguns testes no meu sistema OpenBSD, usando um arquivo de 1.1GB, o cut + grep é na verdade quase 50% mais rápido que awk (8 segundos vs. 15 segundos). E uma solução grep pura ( grep -Ec '\<TY[0-9]' filename , tirada da solução da glenn ) leva 13 segundos.

Portanto, se a string é escolhida apenas do segundo campo, pode-se ganhar algum tempo extraindo apenas esse campo antes de combinar.

    
por 21.06.2018 / 20:47
2

Você deseja usar um limite de palavra em vez da âncora de início de linha:

$ grep -Ec '\<TY[0-9]' file
2

Nota: isso é uma contagem de todas as linhas com uma "palavra TY". Não é uma contagem de todas as palavras "TY". Se você pode ter mais de um por linha, então

$ grep -Eo '\<TY[0-9]' file | wc -l
    
por 21.06.2018 / 20:45
1

Se você quiser encontrar o número de ocorrências de um campo delimitado por , que começa com TY e é seguido por qualquer número de dígitos decimais, você pode:

<file perl -lne '$n += () = /(?<![^,])TY\d+(?![^,])/g; END{print 0+$n}'

Que em uma entrada como:

TY1,TY2,TY,TYFOO
TY213,X-TY2,TY4

retornaria 4 ( TY1 , TY2 , TY213 , TY4 ).

(?<!...) e (?!...) são, respectivamente, operadores de look behing e ahead negativos. Então, aqui, estamos procurando TY seguido por um ou mais ( + ) dígitos ( \d ), desde que não seja precedido nem seguido por um caractere diferente de , .

Outra maneira de fazer isso seria converter , s em novas linhas e contar o número de linhas resultantes que começam com TY seguido por um ou mais dígitos:

<file tr , '\n' | LC_ALL=C grep -xEc 'TY[[:digit:]]+'

(no meu sistema, isso é cerca de 10 vezes mais rápido que a solução perl )

    
por 21.06.2018 / 20:51

Tags