在bash中获取列中唯一值的计数

在bash中获取列中唯一值的计数,bash,command-line,frequency,Bash,Command Line,Frequency,我有几个列的制表符分隔的文件。我想为文件夹中的所有文件计算列中不同值的出现频率,并按计数的降序排序(首先是最高计数)。在Linux命令行环境中如何实现这一点 它可以使用任何常见的命令行语言,如awk、perl、python等。作者建议使用这个漂亮的awk脚本,它可以打印单词及其频率 可能的变化: 您可以通过管道sort-nr(以及反向word和freq[word])以降序查看结果 如果需要特定列,可以省略for循环,只需编写freq[3]++-将3替换为列号 下面是: # wordfreq

我有几个列的制表符分隔的文件。我想为文件夹中的所有文件计算列中不同值的出现频率,并按计数的降序排序(首先是最高计数)。在Linux命令行环境中如何实现这一点

它可以使用任何常见的命令行语言,如awk、perl、python等。

作者建议使用这个漂亮的awk脚本,它可以打印单词及其频率

可能的变化:

  • 您可以通过管道
    sort-nr
    (以及反向
    word
    freq[word]
    )以降序查看结果
  • 如果需要特定列,可以省略for循环,只需编写
    freq[3]++
    -将3替换为列号
下面是:

 # 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]
 }
#wordfreq.awk--打印词频列表
{
$0=tolower($0)#删除案例区分
#删除标点符号
gsub(/[^[:alnum:][u[:blank:][]/,“”,$0)
对于(i=1;iRuby(1.9+)

!/usr/bin/env ruby
Dir[“*”]。每个do |文件|
h=散列。新建(0)
打开(文件)。每行|
行.嚼.裂(“\t”)。每个都有|
h[w]+=1
结束
结束
h、 排序{a,b{b[1]a[1]}。每个{x,y}打印“{x}:{y}\n”
结束

要查看第二列的频率计数(例如):

fileA.txt

z    z    a
a    b    c
w    d    e
fileB.txt

t    r    e
z    d    a
a    g    c
fileC.txt

z    r    a
v    d    c
a    m    c
结果:

  3 d
  2 r
  1 z
  1 m
  1 g
  1 b

以下是在shell中执行此操作的方法:

FIELD=2
cut -f $FIELD * | sort| uniq -c |sort -nr
这正是bash擅长的事情。

Perl 此代码计算所有列的出现次数,并为每个列打印排序报告:

# 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"
    }
}
.csv输入 如果您的输入文件是.csv,请将
/\s+/
更改为
/,/

混淆 在一场丑陋的竞赛中,Perl的装备尤其精良。
这一班轮的作用相同:

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*
perl-lane'用于$i(0..$#F){$g[$i]{$F[$i]}++};END{for$j(0..$#g){print“$j:”;for$k(排序{$g[$j]{$b}$g[$j]{$a}}}键%{$g[$j]}}{$a cmp$b}键%{$g[$j]}}}}}{print“$k$g[$j]{$j]}}*

很棒的示例脚本。它演示了awk的许多功能。该脚本有助于我确定Excel工作簿中哪些行是我真正需要注意的:)(将Excel内容复制到文本文件中,使用awk,然后,瞧!我可以为grep-n创建一个模式文件)。这很有趣,因为我使用了它,而且它很有效,而且我对ruby的丑陋感到惊讶。我认为perl很糟糕!为了ruby的辩护,这真的可以整理一下。例如,使用
每个\u和\u object
,等等。简言之,这写得有点粗糙。“排序”当然……ar!:)有点独特的东西。:P(顺便说一句,使用
-d,
用逗号或任何其他分隔符分隔字段)。我使用了
cut-f 1-d'
。非常感谢。)
# 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"
    }
}
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
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*