打印重复计数而不删除终端中的重复项

时间:2017-03-28 00:46:23

标签: unix awk terminal gnu-coreutils

我是初次使用Mac上的终端并且有一个大的.tsv文件,其中包含一个项目列表,旁边有两个值。我希望能够在第一次出现的项目旁边打印重复项的数量而不删除其他数据。

我知道cut -f 1 |排序| uniq -c但这会删除我想保留用于分析的大量有价值的数据。我正在阅读有关awk和grep的内容,但我想我可以使用一些帮助。

这是我尝试处理的文件的示例:

fruit   number  reference
apple   12  342
apple   13  345
apple   43  4772
banana  19  234
banana  73  3242
peach   131 53423
peach   234 3266
peach   242 324
peach   131 56758
peaches 29  2434

理想情况下,输出看起来像这样:

fruit   number  reference   fruit_count
apple   12  342 3
apple   13  345 
apple   43  4772    
banana  19  234 2
banana  73  3242    
peach   131 53423   4
peach   234 3266    
peach   242 324 
peach   131 56758   
peaches 29  2434    1

这样的事情是否可能?我可以使用公式获得所需的输出excel,但文件太大并且一直在崩溃我。任何帮助将不胜感激。

编辑:添加我当前的解决方案(不符合我的要求)

cut -f 1 fruitsample.txt | sort | uniq -c | sed -e 's/ *//' -e 's/ / /'

这给了我预期的计数,用tab字符替换uniq -c的标准计数+空间输出,但它也对标题行进行排序并删除第2和第3列。

在Excel上,我可以使用公式=IF(COUNTIF(A$2:A2,A2)=1,COUNTIF(A:A,A2),"")并填写它。我正在使用的文件是将近680K行的数据,并且Excel扼流圈试图计算那么多行。

正如我所提到的,我是一名寻找指导的初学者。我不熟悉awk或grep。再次感谢!

3 个答案:

答案 0 :(得分:2)

awk救援!

awk 'NR==FNR {a[$1]++; next} 
     FNR==1  {print $0, "fruit_count"; next} 
     $1 in a {$(NF+1)=a[$1]; delete a[$1]}1' file{,} | 
column -t

fruit    number  reference  fruit_count
apple    12      342        3
apple    13      345
apple    43      4772
banana   19      234        2
banana   73      3242
peach    131     53423      4
peach    234     3266
peach    242     324
peach    131     56758
peaches  29      2434       1

用于解释主要思想我将使用更简单的结构而不使用标题和未排序的数据

$ cat file
apple
banana
apple
apple
cherry
banana

$ awk 'NR==FNR {a[$1]++; next}            # in the first pass, save key counts
                $1 in a                   # if the key in map
                        {$(NF+1)=a[$1];   # add the count as a last column
                         delete a[$1]}    # remove key from map
                1                         # print
       ' file{,} |                        # bash shorthand for: file file
  column -t                               # pretty print columns 


apple   3
banana  2
apple
apple
cherry  1
banana

对于简化示例,使用unix工具链可以实现与

相同的功能
join -a1 -11 -22 -o1.2,2.1 <(cat -n file) <(cat -n file | sort -k2 | uniq -c -f1)

添加标题将需要更多的杂耍;它是awk闪耀的地方。

答案 1 :(得分:0)

另一个使用awk和double - tac s:

$ tac file | awk '
NR>1 {print q, (p==$1?"":++c)}                  # p previous first field, q previous record
     {c=(p==$1?c+1:0); p=$1; q=$0}              # c is the counter
END  {print q, "fruit_count"}
' | tac
fruit   number  reference fruit_count
apple   12  342 3
apple   13  345
apple   43  4772
banana  19  234 2
banana  73  3242
peach   131 53423 4
peach   234 3266
peach   242 324
peach   131 56758
peaches 29  2434 1

答案 2 :(得分:0)

这可以在输入文件的单次传递中执行您想要的操作,并且一次只将1个水果的值存储在内存中,因此尽管文件对于MS-Excel来说太大,它也不会出现性能或内存问题:

<ContentPresenter ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>