Como encontrar freqüência de ocorrências de strings contidas em um arquivo?

4

Eu tenho um arquivo que contém uma lista de URLs do formulário

EDITAR

http://www.google.com/absd/siidfs/kfd837382$%^$&,

www.google.com,

google.com

yahoo.com/list/page/jhfjkshdjf...

Eu quero escrever um script que mostrará a seguinte saída

 google.com : 2
http://www.google.com: 1
yahoo.com : 1 

Eu estou preso com a parte que eu tenho que ler as URLs do arquivo e verificar o arquivo inteiro novamente. Eu sou novo no bash scripting e, portanto, não sei como fazer isso.

    
por coder 27.10.2013 / 04:43

2 respostas

7

Arquivo de entrada original

Assumindo o seguinte formato de entrada:

http://www.google.com,

www.google.com,

google.com

yahoo.com

Com um resultado assim:

google.com : 3 
yahoo.com : 1 

É difícil determinar toda a situação em que você está, mas, dada a saída que você está nos mostrando, eu estaria inclinado a converter o arquivo de entrada primeiro, para que todas as linhas fiquem no formato:

google.com
google.com
google.com
yahoo.com

E, em seguida, execute este arquivo por meio do seguinte conjunto de comandos:

$ grep -v "^$" data.txt | \
      sed -e 's/,$//' -e 's/.*\.\(.*\)\.\(.*\)$/./' | \
      sort | uniq -c
      3 google.com
      1 yahoo.com

Você pode limpar o formato da saída para que corresponda ao que você deseja da seguinte forma:

$ grep -v "^$" data.txt | \
      sed -e 's/,$//' -e 's/.*\.\(.*\)\.\(.*\)$/./' | \
      sort | uniq -c | \
      awk '{printf "%s : %s\n", $1, $2}'
      google.com : 3
      yahoo.com : 1

EDIT # 1

O OP teve uma pergunta de acompanhamento em que ele alterou as entradas no exemplo. Então, para contar este tipo de entrada:

http://www.google.com/absd/siidfs/kfd837382$%^$&,

www.google.com,

google.com

yahoo.com/list/page/jhfjkshdjf...

Você pode usar este verso adaptado do primeiro exemplo:

$ grep -v "^$" data2.txt | \
      sed -e 's/,$//' \
          -e 's#\(http://[^/]\+\).*##' \
          -e '/^[^http]/ s/^www\.//' \
          -e '/^[^http]/ s#\([^/]\+\).*$##' | \
          sort | uniq -c | \
          awk '{printf "%s : %s\n", $1, $2}'
2 : google.com
1 : http://www.google.com
1 : yahoo.com
    
por 27.10.2013 / 04:56
4

Você provavelmente deseja usar sort e uniq -c para obter as contagens corretas e, em seguida, usar sed ou awk para fazer a formatação final. Algo parecido com isto:

sort file | uniq -c | awk '{printf "%s : %s\n", $1, $2}'

Sua pergunta original provavelmente poderia ser respondida com o mesmo pipeline básico, mas primeiro editando a entrada:

sed -e 's/http:\/\///' -e 's/^www\.//' file | sort | uniq -c |
awk '{printf "%s : %s\n", $1, $2}'

Se isso não for exatamente correto, você poderá mexer com os comandos sed e awk para obter os formulários de nome de host e o formato de saída corretos. Por exemplo, para limpar o lado direito de URLs mais longos:

sed -e 's/http:\/\///' -e 's/^www\.//' -e 's/\/..*$//' file |
sort | uniq -c |
awk '{printf "%s : %s\n", $1, $2}'
    
por 27.10.2013 / 04:55