我想根据每一行的内容对文件执行两种不同的排序和计数。
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位数字开头,但是这一次,请保留整个列的值并以此为依据进行排序。
我尝试过的方法:
| sort | uniq -c | sort -nr
表示以^ \ d \ d \ d和
对于不满足上述正则表达式的用户而言,是否相同,但是使用sed
或awk
还是有更优雅的方式吗?
答案 0 :(得分:2)
$ 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
答案 1 :(得分: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
EDIT1:
$ 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
$