Getting the count of unique values in a column in bash

后端 未结 5 886
一整个雨季
一整个雨季 2021-01-30 08:14

I have tab delimited files with several columns. I want to count the frequency of occurrence of the different values in a column for all the files in a folder and sort them in d

5条回答
  •  隐瞒了意图╮
    2021-01-30 08:32

    Perl

    This code computes the occurrences of all columns, and prints a sorted report for each of them:

    # 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"
        }
    }
    

    Save the text as columnvalues.pl
    Run it as: perl columnvalues.pl files*

    Explanation

    In the top-level while loop:
    * Loop over each line of the combined input files
    * Split the line into the @Fields array
    * For every column, increment the result array-of-hashes data structure

    In the top-level for loop:
    * Loop over the result array
    * Print the column number
    * Get the values used in that column
    * Sort the values by the number of occurrences
    * Secondary sort based on the value (for example b vs g vs m vs z)
    * Iterate through the result hash, using the sorted list
    * Print the value and number of each occurrence

    Results based on the sample input files provided by @Dennis

    column 0:
     a 3
     z 3
     t 1
     v 1
     w 1
    column 1:
     d 3
     r 2
     b 1
     g 1
     m 1
     z 1
    column 2:
     c 4
     a 3
     e 2
    

    .csv input

    If your input files are .csv, change /\s+/ to /,/

    Obfuscation

    In an ugly contest, Perl is particularly well equipped.
    This one-liner does the same:

    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*
    

提交回复
热议问题