按第一列计数,按第二列计算不同,并按第一列分组输出?

Dam*_*emi 5 awk text-processing csv

我需要一个 Unix 命令来读取一个带有以下示例的 CSV 文件(超过 700M 行):

A, 10
B, 11
C, 12
A, 10
B, 12
D, 10
A, 12
C, 12
Run Code Online (Sandbox Code Playgroud)

该命令将计算第一列中出现的次数,然后计算第 2 列中不同出现的次数,并按第一列中的条目对输出进行分组。这样输出将如下所示:

A, 3, 2
B, 2, 2
C, 2, 1
D, 1, 1 
Run Code Online (Sandbox Code Playgroud)

Kus*_*nda 3

要获取输出的前两列:

$ cut -d, -f1 <file | sort | uniq -c | awk -vOFS=, '{ print $2, $1 }'
A,3
B,2
C,2
D,1
Run Code Online (Sandbox Code Playgroud)

这会提取原始文件的第一列,对其进行排序并计算重复条目的数量。最后awk只是交换列并在它们之间插入逗号。

最后一栏可能有

$ sort -u <file | cut -d, -f1 | uniq -c | awk -vOFS=, '{ print $1 }'
2
2
1
1
Run Code Online (Sandbox Code Playgroud)

这会对原始数据进行排序并丢弃重复项。然后提取第一列以及该列的重复项数然后提取第一列并计算最后awk仅提取计数。

bash使用和组合这些paste

$ paste -d, <( cut -d, -f1 <file | sort    | uniq -c | awk -vOFS=, '{ print $2, $1 }' ) \
            <( sort -u <file | cut -d, -f1 | uniq -c | awk -vOFS=, '{ print $1 }' )
A,3,2
B,2,2
C,2,1
D,1,1
Run Code Online (Sandbox Code Playgroud)

如果您对数据进行预先排序,这可能会稍微缩短(并大大加快):

$ sort -o file file

$ paste -d, <( cut -d, -f1 <file        | uniq -c | awk -vOFS=, '{ print $2, $1 }' ) \
            <( uniq <file | cut -d, -f1 | uniq -c | awk -vOFS=, '{ print $1 }' )
A,3,2
B,2,2
C,2,1
D,1,1
Run Code Online (Sandbox Code Playgroud)