我有一个如下所示的数据文件:
123456, 1623326
123456, 2346525
123457, 2435466
123458, 2564252
123456, 2435145
第一列是“ID” - 一个字符串变量。第二栏对我来说无关紧要。我想最终得到
123456, 3
123457, 1
123458, 1
其中第二列现在计算原始文件中与第一列中唯一“ID”对应的条目数。
bash或perl中的任何解决方案都会很棒。即使Stata也会很好,但我认为这在Stata中更难做到。如果有任何不清楚的地方,请告诉我。
答案 0 :(得分:6)
在Stata中,这只是
contract ID
答案 1 :(得分:5)
cut -d',' -f1 in.txt | sort | uniq -c | awk '{print $2 ", " $1}'
给出:
123456, 3
123457, 1
123458, 1
答案 2 :(得分:3)
将第一个字段中的数字拆分并将其用作哈希键,每次增加其计数
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;
正则表达式在一行的开头捕获连续的数字。当它作为列表返回时,我们将其编入索引以获取用作哈希键的数字(/.../)[0]
。当第一次看到一个数字时,它会作为键添加到哈希值,并且由于++
,其值设置为1。当看到已作为键存在的数字时,其值将增加++
。这是一个典型的频率计数器。
将您的号码放在档案data_cnt.txt
中,此输出
123457, 1 123456, 3 123458, 1
如果需要,可以按哈希值对输出进行排序
say "$_, $cnt{$_}" for sort { $cnt{$b} <=> $cnt{$a} } (keys %cnt);
打印
123456, 3 123457, 1 123458, 1
如果出于某种原因,这可以适合单线,
perl -nE '
$cnt{(/^(\d+)/)[0]}++;
}{ say "$_, $cnt{$_}" for sort { $cnt{$b} <=> $cnt{$a} } keys %cnt
' data_cnt.txt
应在终端输入一行。 }{
是END { }
块的缩写。代码与上面的简短脚本相同。 -E
与-e
相同,但启用了功能say
。
答案 3 :(得分:3)
这会计算前六个字符相同的行数:
$ sort file | uniq -c -w6
3 123456, 1623326
1 123457, 2435466
1 123458, 2564252
来自man uniq
:
-w, - check-chars = N
在行中比较不超过N个字符
答案 4 :(得分:2)
您可以使用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=", "
设置输入&amp;输出字段分隔符为", "
counts[$1]++{}
为每个实例递增counts
数组1
中第一列存储的计数器。 {}
同样无所事事END
块中,我们遍历counts
数组并打印每个唯一id
和count
答案 5 :(得分:2)
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'push@a,$F[0]if!$s{$F[0]}++}{say"$_, $s{$_}"for@a'
或仅以伪随机顺序
perl -F',' -anE'$s{$F[0]}++}{say"$_, $s{$_}"for keys%s'
等等。
答案 6 :(得分:1)
Perl one-liner:
perl -naE '$h{$F[0]}++}{for(sort keys %h){say "$_ $h{$_}"}' file.txt
123456, 3
123457, 1
123458, 1
-n
遍历文件中的每一行
-a
在空白处拆分每一行,并用每个条目填充@F
数组
}{
表示END
块,它允许我们在处理完文件中的所有行后迭代哈希
答案 7 :(得分:0)
在Perl中
$ perl -MData::Dump -ne "++@n{/(\d+)/}; END {dd \%n}" data.txt
{ 123456 => 3, 123457 => 1, 123458 => 1 }
答案 8 :(得分:0)