Devo trovare le 10 parole più frequenti in un file .csv.
Il file è strutturato in modo che ogni riga contenga parole separate da virgole. Se la stessa parola viene ripetuta più di una volta nella stessa riga, dovrebbe essere contata come una.
Quindi, nell'esempio seguente:
green,blue,blue,yellow,red,yellow
red,blue,green,green,green,brown
verde, blu e rosso devono essere contati come 2 e giallo e marrone come 1
So che domande simili sono state poste in precedenza e una soluzione era:
<file.csv tr -c '[:alnum:]' '[\n*]' | sort|uniq -c|sort -nr|head -10
Ma questo conterà il numero di volte in cui una parola appare nella stessa riga, in questo modo:
4 green
3 blue
2 yellow
2 red
1 brown
e questo non è effettivamente ciò di cui ho bisogno.
Qualche aiuto? Inoltre apprezzerò una breve spiegazione del comando e perché il comando che ho trovato in domande simili non fa ciò di cui ho bisogno.
Risposta accettata:
Probabilmente raggiungerei Perl
- Usa
uniq
dallaList::Util
modulo per deduplicare ogni riga. - Utilizza un hash per contare le occorrenze risultanti.
Ad esempio
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
Se non hai alcuna opzione tranne il sort
e uniq
coreutils, quindi puoi implementare un algoritmo simile con l'aggiunta di un ciclo di 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
tuttavia, fai riferimento a Perché l'utilizzo di un ciclo di shell per elaborare il testo è considerato una cattiva pratica?