Je dois trouver les 10 mots les plus fréquents dans un fichier .csv.
Le fichier est structuré de sorte que chaque ligne contienne des mots séparés par des virgules. Si le même mot est répété plus d'une fois dans la même ligne, il doit être compté comme un.
Ainsi, dans l'exemple ci-dessous :
green,blue,blue,yellow,red,yellow
red,blue,green,green,green,brown
le vert, le bleu et le rouge doivent être comptés comme 2 et le jaune et le marron comme 1
Je sais que des questions similaires ont déjà été posées, et une solution était :
<file.csv tr -c '[:alnum:]' '[\n*]' | sort|uniq -c|sort -nr|head -10
Mais cela comptera le nombre de fois qu'un mot apparaît dans la même ligne, comme ceci :
4 green
3 blue
2 yellow
2 red
1 brown
et ce n'est pas vraiment ce dont j'ai besoin.
Une aide ? J'apprécierai également une brève explication de la commande et pourquoi la commande que j'ai trouvée dans des questions similaires ne fait pas ce dont j'ai besoin.
Réponse acceptée :
J'opterais probablement pour perl
- Utilisez
uniq
de laList::Util
module pour dédupliquer chaque ligne. - Utilisez un hachage pour compter les occurrences résultantes.
Par exemple
perl -MList::Util=uniq -F, -lnE '
map { $h{$_}++ } uniq @F
}{
foreach $k (sort { $h{$b} <=> $h{$a} } keys %h) {say "$h{$k}: $k"}
' file.csv
2: red
2: green
2: blue
1: yellow
1: brown
Si vous n'avez pas d'autre option que le sort
et uniq
coreutils, vous pouvez implémenter un algorithme similaire avec l'ajout d'une boucle shell
while IFS=, read -a words; do
printf '%s\n' "${words[@]}" | sort -u
done < file.csv | sort | uniq -c | sort -rn
2 red
2 green
2 blue
1 yellow
1 brown
cependant, veuillez vous référer à Pourquoi l'utilisation d'une boucle shell pour traiter le texte est-elle considérée comme une mauvaise pratique ?