计算一行的重复列,打印所有行及其计数
Count repeated columns of a line, print all lines and their count
我要:
$ cat file
ABCDEFG, XXX
ABCDEFG, YYY
ABCDEFG, ZZZ
AAAAAAA, XZY
BBBBBBB, XYZ
CCCCCCC, YXZ
DDDDDDD, YZX
CDEFGHI, ZYX
CDEFGHI, XZY
$ cat file | magic
3 ABCDEFG, XXX
3 ABCDEFG, YYY
3 ABCDEFG, ZZZ
1 AAAAAAA, XZY
1 BBBBBBB, XYZ
1 CCCCCCC, YXZ
1 DDDDDDD, YZX
2 CDEFGHI, ZYX
2 CDEFGHI, XZY
所以,预先排序的文件进入,识别第一列中的重复,计算这个重复的行数,打印重复计数加上所有重复的行及其内容,包括第 2 列中的任何内容,它可以是任何东西并且与唯一计数无关。
两个问题:
1) 得到uniq -c
的效果,但不删除重复项。
网上搜索后我真正"hacky"sed -e
的解决方案是这样的:
cat file | cut -d',' -f1 | uniq -c | sed -E -e 's/([0-9][0-9]*) (.*)/echo $(yes | head -)/;e' | sed -E 's/ ([0-9])/;/g' | tr ';' '\n'
我很惊讶地看到 head -
之类的东西在工作,但很好。但是,我觉得应该有一个更简单的方法来解决这个问题。
2) 以上去掉了第二列。我可以先 运行 我的代码,然后 paste
它到原始文件中的第二列,但是文件很大,我希望事情尽可能地高效。
有什么建议吗?
awk 中的一个。很累,所以没有完全测试。希望有用,晚安:
$ awk -F, '
!=p {
for(i=1;i<c;i++)
print c-1,a[i]
c=1
}
{
a[c++]=[=10=]
p=
}
END {
for(i=1;i<c;i++)
print c-1,a[i]
}' file
输出:
3 ABCDEFG,XXX
3 ABCDEFG,YYY
3 ABCDEFG,ZZZ
1 AAAAAAA,XZY
1 BBBBBBB,XYZ
1 CCCCCCC,YXZ
1 DDDDDDD,YZX
2 CDEFGHI,ZYX
2 CDEFGHI,XZY
这是一种使用 awk 的方法,它可以将文件传递两次。在第一遍中,使用关联数组存储第一列的计数。在第二遍中,打印数组值和行本身:
awk -F, 'FNR==NR { a[]++; next } { print a[], [=10=] }' file{,}
结果:
3 ABCDEFG, XXX
3 ABCDEFG, YYY
3 ABCDEFG, ZZZ
1 AAAAAAA, XZY
1 BBBBBBB, XYZ
1 CCCCCCC, YXZ
1 DDDDDDD, YZX
2 CDEFGHI, ZYX
2 CDEFGHI, XZY
我要:
$ cat file
ABCDEFG, XXX
ABCDEFG, YYY
ABCDEFG, ZZZ
AAAAAAA, XZY
BBBBBBB, XYZ
CCCCCCC, YXZ
DDDDDDD, YZX
CDEFGHI, ZYX
CDEFGHI, XZY
$ cat file | magic
3 ABCDEFG, XXX
3 ABCDEFG, YYY
3 ABCDEFG, ZZZ
1 AAAAAAA, XZY
1 BBBBBBB, XYZ
1 CCCCCCC, YXZ
1 DDDDDDD, YZX
2 CDEFGHI, ZYX
2 CDEFGHI, XZY
所以,预先排序的文件进入,识别第一列中的重复,计算这个重复的行数,打印重复计数加上所有重复的行及其内容,包括第 2 列中的任何内容,它可以是任何东西并且与唯一计数无关。 两个问题:
1) 得到uniq -c
的效果,但不删除重复项。
网上搜索后我真正"hacky"sed -e
的解决方案是这样的:
cat file | cut -d',' -f1 | uniq -c | sed -E -e 's/([0-9][0-9]*) (.*)/echo $(yes | head -)/;e' | sed -E 's/ ([0-9])/;/g' | tr ';' '\n'
我很惊讶地看到 head -
之类的东西在工作,但很好。但是,我觉得应该有一个更简单的方法来解决这个问题。
2) 以上去掉了第二列。我可以先 运行 我的代码,然后 paste
它到原始文件中的第二列,但是文件很大,我希望事情尽可能地高效。
有什么建议吗?
awk 中的一个。很累,所以没有完全测试。希望有用,晚安:
$ awk -F, '
!=p {
for(i=1;i<c;i++)
print c-1,a[i]
c=1
}
{
a[c++]=[=10=]
p=
}
END {
for(i=1;i<c;i++)
print c-1,a[i]
}' file
输出:
3 ABCDEFG,XXX
3 ABCDEFG,YYY
3 ABCDEFG,ZZZ
1 AAAAAAA,XZY
1 BBBBBBB,XYZ
1 CCCCCCC,YXZ
1 DDDDDDD,YZX
2 CDEFGHI,ZYX
2 CDEFGHI,XZY
这是一种使用 awk 的方法,它可以将文件传递两次。在第一遍中,使用关联数组存储第一列的计数。在第二遍中,打印数组值和行本身:
awk -F, 'FNR==NR { a[]++; next } { print a[], [=10=] }' file{,}
结果:
3 ABCDEFG, XXX
3 ABCDEFG, YYY
3 ABCDEFG, ZZZ
1 AAAAAAA, XZY
1 BBBBBBB, XYZ
1 CCCCCCC, YXZ
1 DDDDDDD, YZX
2 CDEFGHI, ZYX
2 CDEFGHI, XZY