count, groupby with sed, or awk



我想根据每一行的内容对文件执行两种不同的排序和计数。1.我需要获取.tsv文件的第一列我想按以三位数字开头的每一行进行分组,只保留前三位数字,对于其他所有内容,只需对第一列中句子的全部出现次数进行排序和计数。

样本数据:

687/878 9
890987  4
01a 55
1b  8743917
890a    34
abcdee  987
dfeqfe  fkdjald
890897  34213
6878853 834
32fasd  53891
abcdee  8794371
abd 873

结果:

687 2
890 3
01a 1
1b  1
32fasd  1
abd 1
dfeqfe  1
abcdee  2

我也很感激的解决方案

还考虑了像这样的样本输入

687/878 9
890987  4
01a     55
1b      8743917
890a    34
abcdee  987
dfeqfe  545
890897  34213
6878853 834
(632)fasd  53891
(88)abcdee  8794371
abd     873

所以第一列可能有像(,),#,'这样的值,所有类型的字符

因此输出将有两列,第一列提取值,第二列提取新计数,从源文件中提取新值。

再次优选输出格式tsv。

所以我需要提取所有以^\d\d\d,然后对于这三个第一位数字,对唯一值进行排序和计数,

但是在第二遍中,也对每一行做同样的操作,这不是以3位数字开始的,但这次,保持整列的值并按其排序。

我尝试过的:以^\d\d\d和开头的行的| sort | uniq -c | sort -nr

对于那些不满足上述正则表达式的正则表达式也是如此,但有没有更优雅的方法使用sedawk

$ cat tst.awk
BEGIN { FS=OFS="t" }
{ cnt[/^[0-9]{3}/ ? substr($1,1,3) : $1]++ }
END {
for (key in cnt) {
print (key !~ /^[0-9]{3}/), cnt[key], key, cnt[key]
}
}
$ awk -f tst.awk file | sort -k1,2n | cut -f3-
687     1
890     2
abcdee  1

您可以尝试Perl

$ cat nefijaka.txt
687     878     9
890987  4
890a    34
abcdee  987
$ perl -lne  ' /^(d{3})|(S+)/; $x=$1?$1:$2; $kv{$x}++; END { print "$_t$kv{$_}" for (sort keys %kv) } ' nefijaka.txt
687     1
890     2
abcdee  1
$

您可以通过管道对其进行排序并对值进行排序。。

$ perl -lne  ' /^(d{3})|(S+)/; $x=$1?$1:$2; $kv{$x}++; END { print "$_t$kv{$_}" for (sort keys %kv) } ' nefijaka.txt | sort -k2 -nr
890     2
abcdee  1
687     1

第1版:

$ cat nefijaka.txt2
687     878     9
890987  4
890a    34
abcdee  987
a word and then 23
$ perl -lne  ' /^(d{3})|(.+?t)/; $x=$1?$1:$2; $x=~s/t//g; $kv{$x}++; END { print "$_t$kv{$_}" for (sort keys %kv) } ' nefijaka.txt2
687     1
890     2
a word and then 1
abcdee  1
$

最新更新