Mam pliki rozdzielane tabulatorami z kilkoma kolumnami. Chcę policzyć częstotliwość występowania różnych wartości w kolumnie dla wszystkich plików w folderze i posortować je w kolejności malejącej (najpierw od największej liczby). Jak mógłbym to osiągnąć w środowisku wiersza poleceń Linuksa?
Może używać dowolnego popularnego języka linii poleceń, takiego jak awk, perl, python itp.
bash
command-line
frequency
sfactor
źródło
źródło
-d,
do oddzielania pól przecinkami lub innymi ogranicznikami).cut -f 1 -d ' '
. Dziękuję bardzo. :)Witryna GNU proponuje ten fajny skrypt awk, który wypisuje zarówno słowa, jak i ich częstotliwość.
Możliwe zmiany:
sort -nr
(i odwrócićword
ifreq[word]
), aby zobaczyć wynik w porządku malejącym.freq[3]++
- zamień 3 na numer kolumny.Tutaj idzie:
# wordfreq.awk --- print list of word frequencies { $0 = tolower($0) # remove case distinctions # remove punctuation gsub(/[^[:alnum:]_[:blank:]]/, "", $0) for (i = 1; i <= NF; i++) freq[$i]++ } END { for (word in freq) printf "%s\t%d\n", word, freq[word] }
źródło
Perl
Ten kod oblicza wystąpienia wszystkich kolumn i wyświetla posortowany raport dla każdej z nich:
# columnvalues.pl while (<>) { @Fields = split /\s+/; for $i ( 0 .. $#Fields ) { $result[$i]{$Fields[$i]}++ }; } for $j ( 0 .. $#result ) { print "column $j:\n"; @values = keys %{$result[$j]}; @sorted = sort { $result[$j]{$b} <=> $result[$j]{$a} || $a cmp $b } @values; for $k ( @sorted ) { print " $k $result[$j]{$k}\n" } }
Zapisz tekst jako columnvalues.pl
Uruchom go jako:
perl columnvalues.pl files*
Wyjaśnienie
W pętli while na najwyższym poziomie:
* Pętla nad każdym wierszem połączonych plików wejściowych
* Podziel wiersz na tablicę @Fields
* Dla każdej kolumny zwiększ wynikową strukturę danych tablicy skrótów
Na najwyższym poziomie pętli for:
* Pętla nad tablicą wyników
* Wydrukuj numer kolumny
* Pobierz wartości użyte w tej kolumnie
* Sortuj wartości według liczby wystąpień
* Drugorzędne sortowanie na podstawie wartości (na przykład b vs g vs m vs z)
* Iteruj przez skrót wyniku, używając posortowanej listy
* Wydrukuj wartość i liczbę każdego wystąpienia
Wyniki oparte na przykładowych plikach wejściowych dostarczonych przez @Dennis
.csv wejście
Jeśli pliki wejściowe to .csv, zmień
/\s+/
na/,/
Maskowanie
W brzydkim konkursie Perl jest szczególnie dobrze wyposażony.
Ta jedna linijka robi to samo:
perl -lane 'for $i (0..$#F){$g[$i]{$F[$i]}++};END{for $j (0..$#g){print "$j:";for $k (sort{$g[$j]{$b}<=>$g[$j]{$a}||$a cmp $b} keys %{$g[$j]}){print " $k $g[$j]{$k}"}}}' files*
źródło
Rubin (1,9+)
#!/usr/bin/env ruby Dir["*"].each do |file| h=Hash.new(0) open(file).each do |row| row.chomp.split("\t").each do |w| h[ w ] += 1 end end h.sort{|a,b| b[1]<=>a[1] }.each{|x,y| print "#{x}:#{y}\n" } end
źródło
each_with_object
między innymi. Krótko mówiąc, jest to nieco rażąco napisane.