计算bash中第一列中具有相同项的行数
我有一个如下所示的数据文件:计算bash中第一列中具有相同项的行数,bash,perl,shell,stata,Bash,Perl,Shell,Stata,我有一个如下所示的数据文件: 123456, 1623326 123456, 2346525 123457, 2435466 123458, 2564252 123456, 2435145 第一列是“ID”——一个字符串变量。第二栏对我来说无关紧要。我想和你在一起 123456, 3 123457, 1 123458, 1 其中,第二列现在统计原始文件中与第一列中唯一“ID”对应的条目数 bash或perl中的任何解决方案都是非常棒的。即使是斯塔塔也不错,但我觉得在斯塔塔这样做更难。如果有什
123456, 1623326
123456, 2346525
123457, 2435466
123458, 2564252
123456, 2435145
第一列是“ID”——一个字符串变量。第二栏对我来说无关紧要。我想和你在一起
123456, 3
123457, 1
123458, 1
其中,第二列现在统计原始文件中与第一列中唯一“ID”对应的条目数
bash或perl中的任何解决方案都是非常棒的。即使是斯塔塔也不错,但我觉得在斯塔塔这样做更难。如果有什么不清楚的地方,请告诉我 您可以使用awk:
awk 'BEGIN{FS=OFS=", "} counts[$1]++{} END{for (i in counts) print i, counts[i]}' file
123456, 3
123457, 1
123458, 1
将输入和输出字段分隔符设置为FS=OFS=“,”
,“
为每个实例将数组counts[$1]+{}
中第一列存储的计数器递增counts
<代码>{}是一样的,什么都不做1
- 在
块中,我们迭代END
数组,并打印每个唯一的counts
和id
count
123456, 3
123457, 1
123458, 1
拆分第一个字段中的数字并将其用作哈希键,每次都增加其计数
use warnings;
use strict;
my $file = 'data_cnt.txt';
open my $fh, '<', $file or die "Can't open $file: $!";
my %cnt;
while (<$fh>) {
$cnt{(/^(\d+)/)[0]}++;
}
print "$_, $cnt{$_}\n" for keys %cnt;
如果需要,可以按散列值对输出进行排序
say "$_, $cnt{$_}" for sort { $cnt{$b} <=> $cnt{$a} } (keys %cnt);
对排序{$cnt{$b}$cnt{$a}(键%cnt)说“$\$cnt{$\}”;
印刷品
123456, 3
123457, 1
123458, 1
123456, 3
123457, 1
123458, 1
如果出于某种原因首选,这可以装入一个衬里中
perl -nE '
$cnt{(/^(\d+)/)[0]}++;
}{ say "$_, $cnt{$_}" for sort { $cnt{$b} <=> $cnt{$a} } keys %cnt
' data_cnt.txt
perl-nE'
$cnt{(/^(\d+/)[0]}++;
}{对排序{$cnt{$b}$cnt{$a}}键%cnt说“$\$cnt{$\}”
'data_cnt.txt
它应该作为一个终端的一行输入。
{
是END{}
块的缩写。代码与上面的短脚本相同。-E
与-E
相同,同时它启用了功能比如说这统计了具有相同前六个字符的行数:
$ sort file | uniq -c -w6
3 123456, 1623326
1 123457, 2435466
1 123458, 2564252
文档
从man uniq的开始:
-w、 --检查字符=N
比较行中不超过N个字符
Perl一行程序:
perl -naE '$h{$F[0]}++}{for(sort keys %h){say "$_ $h{$_}"}' file.txt
123456, 3
123457, 1
123458, 1
-n
在文件中的每一行上循环
-a
在空白处拆分每一行,并用每个条目填充@F
数组
}{
表示一个结束
块,该块允许我们在处理完文件中的所有行之后迭代散列
contract ID
cut
,sort
,uniq
,sed
版本
cut -d',' -f1 | sort | uniq -c | sed 's/^ *\([^ ]*\) \(.*\)/\2, \1/'
或简单的Perl版本,按第一列排序
perl -F',' -anE'$s{$F[0]}++}{say"$_, $s{$_}"for sort keys%s'
perl -F',' -anE'$s{$F[0]}++}{say"$_, $s{$_}"for sort{$s{$b}<=>$s{$a}or$a cmp$b}keys%s'
或按计数降序排序,然后按第一列排序
perl -F',' -anE'$s{$F[0]}++}{say"$_, $s{$_}"for sort keys%s'
perl -F',' -anE'$s{$F[0]}++}{say"$_, $s{$_}"for sort{$s{$b}<=>$s{$a}or$a cmp$b}keys%s'
或者只是伪随机顺序
perl -F',' -anE'$s{$F[0]}++}{say"$_, $s{$_}"for keys%s'
等等。在Perl中
$ perl -MData::Dump -ne "++@n{/(\d+)/}; END {dd \%n}" data.txt
{ 123456 => 3, 123457 => 1, 123458 => 1 }
与:
我曾经读过一篇文章,当你给一匹海马提供两只虾作为食物时,它们会饿死,因为它们无法决定选哪一只。看来你现在也遇到了类似的麻烦;-)@PerlDog…有一些很好的不同方法的答案:)@stevieb是的。我最喜欢一只,因为我学到了一些新的东西(但为了不影响海马,我不会说是哪一个)。但我们缺乏一个stata解决方案(不管是什么).我忍不住笑了。这是真的吗?哇!看起来有人想发布一个MySQL问题,但过早地点击了提交按钮。很酷。最后选择了这一个哈哈!非常感谢。另一个STATA答案也很棒。真不敢相信我不知道这个命令。。。
$ perl -MData::Dump -ne "++@n{/(\d+)/}; END {dd \%n}" data.txt
{ 123456 => 3, 123457 => 1, 123458 => 1 }
datamash -W -s -g1 count 1 < data
123456, 3
123457, 1
123458, 1