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' ' '
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
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' ' '
$ 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
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
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.
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
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
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.