Tentando encontrar a frequência de palavras em um arquivo usando um script

1

O arquivo que tenho é chamado test e contém as seguintes linhas:

This is a test Test test test There are multiple tests.

Eu quero que a saída seja:

test@3 tests@1 multiple@1 is@1 are@1 a@1 This@1 There@1 Test@1

Eu tenho o seguinte script:

 cat $1 | tr ' ' '\n' > temp # put all words to a new line
    echo -n > file2.txt # clear file2.txt
    for line in $(cat temp)  # trace each line from temp file
    do
    # check if the current line is visited
     grep -q $line file2.txt 
     if [ $line==$temp] 
     then
    count= expr '$count + 1' #count the number of words
     echo $line"@"$count >> file2.txt # add word and frequency to file
     fi
    done
    
por Samurai Bale 01.04.2018 / 18:38

7 respostas

4

Use sort | uniq -c | sort -n para criar uma tabela de frequências. Mais alguns ajustes necessários para obter o formato desejado.

 tr ' ' '\n' < "$1" \
 | sort \
 | uniq -c \
 | sort -rn \
 | awk '{print $2"@"$1}' \
 | tr '\n' ' '
    
por 01.04.2018 / 18:45
2
$ cat >wdbag.py
#!/usr/bin/python

from collections import *
import re, sys

text=' '.join(sys.argv[1:])       

t=Counter(re.findall(r"[\w']+", text.lower()))

for item in t:
  print item+"@"+str(t[item])

$ chmod 755 wdbag.py 

$ ./wdbag.py "This is a test Test test test There are multiple tests."
a@1
tests@1
multiple@1
this@1
is@1
there@1
are@1
test@4

$ ./wdbag.py This is a test Test test test There are multiple tests.
a@1
tests@1
multiple@1
this@1
is@1
there@1
are@1
test@4

Ref: link

    
por 01.04.2018 / 23:39
1

grep + sort + uniq + sed pipeline:

grep -o '[[:alnum:]]*' file | sort | uniq -c | sed -E 's/[[:space:]]*([0-9]+) (.+)/@/'

A saída:

a@1
are@1
is@1
multiple@1
test@3
Test@1
tests@1
There@1
This@1
    
por 01.04.2018 / 18:45
1

Com awk apenas:

 awk -v RS='( |\.|\n)' '{s[$0]++} 
     END{for (x in s) {printf "%s%s", SEP,x"@"s[x]; SEP=" "}; print ""}' infile

Isto define o eparador R ecord S ou um espaço , ponto ou \n ewline , em seguida, salve os campos em uma matriz chamada s com a chave como campos / palavras inteiros e, para cada visto das palavras, incremente as ocorrências na matriz que representa o valor das chaves na matriz.

No loop END sobre os elementos da matriz e primeiro imprima as chaves (campos / palavras) x , a @ e seu valor como ocorrências s[x] .

O SEP é uma variável usada para adicionar espaços entre cada palavra ao imprimir e uma segunda para as próximas palavras.

    
por 01.04.2018 / 19:54
0

Usando o grep e o awk ..

 grep -o '[[:alnum:]]*' file | awk '{ count[$0]++; next}END {ORS=" "; for (x in count)print x"@"count[x];print "\n"}'

testes @ 1 Teste @ 1 múltiplo @ 1 a @ 1 Este @ 1 Existe @ 1 é @ 1 teste @ 3 é @ 1

    
por 01.04.2018 / 19:24
0
gawk '
{
    for(i = 1; i <= NF; i++) {
        arr[$i]++
    }
}
END {
    PROCINFO["sorted_in"] = "@val_num_desc"

    for(i in arr) {
        printf "%s@%s ", i, arr[i]
    }
    print ""
}
' FPAT='[a-zA-Z]+' input.txt

Explicação

PROCINFO["sorted_in"] = "@val_num_desc" - Ordenar por valores de elemento em ordem decrescente (em vez de por índices). Valores escalares são comparados como números. Consulte Pedidos de verificação de matriz predefinidos .

FPAT='[a-zA-Z]+' - Uma expressão regular que descreve o conteúdo dos campos em um registro. Quando definido, gawk                    analisa a entrada em campos, onde os campos correspondem à expressão regular, em vez de                    usando o valor da variável FS como separador de campos.

Entrada

This is a test Test test test There are multiple tests.
This is a test Test test test There are multiple tests.
This is a test Test test test There are multiple tests.

Resultado

test@9 tests@3 Test@3 multiple@3 a@3 This@3 There@3 are@3 is@3 
    
por 01.04.2018 / 22:45
0

Como o OP perguntou no mesmo tipo de formato ...

bash-4.1$ cat test.sh
#!/bin/bash

tr ' ' '\n' < ${1} > temp
while read line
do
    count=$(grep -cw ${line} temp)
    echo -n "${line}@${count} "
done < temp
echo ""

bash-4.1$ bash test.sh test.txt
This@1 is@1 a@1 test@3 Test@1 test@3 test@3 There@1 are@1 multiple@1 tests.@1

bash-4.1$ cat test.txt
This is a test Test test test There are multiple tests.
    
por 02.04.2018 / 04:42