Conte quantas linhas começam com quais caracteres

1

Eu tenho um arquivo com várias linhas em um nome de arquivo.

Eu quero contar quantas linhas começam com o caractere 'a', com 'b' e assim por diante de uma só vez.

Qual comando devo executar?

    
por codeofnode 30.08.2013 / 10:32

2 respostas

2

Tente isto:

<file.txt sed 's/^\(.\).*//' | sort | uniq -c

Ou, se você quiser insensível a maiúsculas, isso:

<file.txt sed 's/^\(.\).*//' | tr a-z A-Z | sort | uniq -c
    
por 30.08.2013 / 10:38
8

Para letras de caracteres simples:

< file cut -c1 | grep '[[:alpha:]]' | LC_ALL=C sort | LC_ALL=C uniq -c | sort -k 2

Para lidar com caracteres combinados, se estiver em uma localidade utf-8:

< file PERLIO=:utf8 perl -Mlocale -MUnicode::Normalize -lne '
  $_=NFKD($_); $n{$&}++ if /^[[:alpha:]]/u && /^\X/u;
  END{for $i (sort keys %n) {print "$n{$i} $i"}}'

(substitua $n{$&} por $n{lc$&} para contagem independente de caso).

Em uma entrada como:

fix
été
-dash-
éléphant
παράλληλα
молчит
alphabet
3com
foo
ɪ-letter
ʃ-letter

Na minha localidade, o primeiro resultado seria:

  1 ɪ
  1 ʃ
  1 a
  1 e
  1 é
  2 f
  1 π
  1 м

Porque éléphant acima (que, a propósito, minha versão do firefox é exibida incorretamente, pois coloca o acento no l ), o primeiro é é escrito como os dois caracteres unicode e e \U0301 (combinando acento agudo), enquanto em été , é o \U00E9 pré-composto e com acento agudo.

E o segundo seria exibido:

1 ɪ
1 ʃ
1 a
2 é
2 f
1 π
1 м

(lá, todas as variantes de é foram convertidas para e\U0301 (a versão decomposta normalizada)).

Enquanto cut -c 1 | grep '[[:alpha:]]' | sort | uniq -c produziria:

  2 ɪ
  1 a
  1 e
  1 é
  2 f
  1 π
  1 м

porque na minha localidade, a ordem de classificação de ɪ e ʃ não está definida, então eles ordenam o mesmo e contam como o mesmo que sort e uniq .

(note que você precisa de um POSIX cut acima. Minha versão do GNU cut não é como trata caracteres como bytes, então eu tive que usar o cut construído em ksh93 para isso). / p>

Se os dados forem apenas US-ASCII, você poderá simplificá-lo para:

(export LC_ALL=C; < file cut -c 1 | grep '[[:alpha:]]' | sort | uniq -c)

Ou se você quiser denunciar 0 para qualquer uma das 52 letras ASCII dos EUA que não foram encontradas:

< file LC_ALL=C awk '{n[substr($0,1,1)]++};END{
  for(i=65;i<=122;i++) if (i < 91 || i > 96) {
    c=sprintf("%c",i);print 0+n[c], c}}'
    
por 30.08.2013 / 10:53