我有一个 CSV,其中的列如下所示:
Team Other Data More Data Result Time
Knicks A F Loss 2p
Celtics B E Win 2p
Lakers C D Loss 3p
Lakers D C Loss 4p
Knicks E B Win 4p
Lakers F A Win 5p
如何读取CSV并输出每支球队的胜负?
例如,我想要的输出如下:
1 Loss Knicks 1 Win Knicks 1 Win Celtics 2 Loss Lakers 1 Win Lakers
现在,我有这个代码:
#!/bin/bash
while IFS=, read -r team result
do
echo $team, $result
done < teams.csv
产生以下输出:
Team, Result
Knicks, Loss
Celtics, Win
Lakers, Loss
Lakers, Loss
Knicks, Win
如何计算并存储每个团队每个结果出现的次数?理想情况下,我希望这些数据按团队排序。
答案1
在中使用数组awk
如果输入文件的字段由一个或多个空白字符分隔,则不必声明字段分隔符:
awk 'NR>1 && NF { league[$1][$4]++ } END { for ( team in league ) for ( results in league[team] ) print league[team][results],results,team }' teams.txt
相同的代码,针对屏幕进行格式化:
awk 'NR>1 && NF { league[$1][$4]++ }
END { for ( team in league )
for ( results in league[team] )
print league[team][results],results,team }' teams.txt
此处,统计联赛(输入文件)中每支球队( ,第一场)的胜负league[$1][$4]++
数( ,第四场)。$4
$1
NR>1
意味着awk
将忽略标题(第一行)。
类似地,NF
( 的简写NF>0
)表示awk
将仅检查包含至少一个字段的行。换句话说,NF
跳过空行。
本NR>1 && NF
节检查输入文件并创建数组。完成后,该END
部分将打印该数组。
如果输入文件的字段以逗号分隔,则添加BEGIN { FS="," ; OFS=" " }
设置输入(FS
)和输出(OFS
)字段分隔符:
awk 'BEGIN { FS="," ; OFS=" " } NR>1 && NF { league[$1][$4]++ } END { for ( team in league ) for ( results in league[team] ) print league[team][results],results,team }' teams.csv
相同的代码,针对屏幕进行格式化:
awk 'BEGIN { FS="," ; OFS=" " }
NR>1 && NF { league[$1][$4]++ }
END { for ( team in league )
for ( results in league[team] )
print league[team][results],results,team }' teams.csv
输出:
1 Win Knicks
1 Loss Knicks
1 Win Lakers
2 Loss Lakers
1 Win Celtics
添加| sort -t " " -k 3 -k 2,2
到该代码的末尾,按团队排序,然后按每个团队的结果排序。
排序输出:
1 Win Celtics
1 Loss Knicks
1 Win Knicks
2 Loss Lakers
1 Win Lakers
答案2
您需要做的就是对文件进行排序并将其传递给以uniq -c
计算唯一出现次数:
sort teams.csv | uniq -c
这应该产生如下输出:
1 Celtics,Win
1 Knicks,Loss
1 Knicks,Win
2 Lakers,Loss
答案3
使用 GNU datamash (和 awk 重新排列列,如果这对你很重要的话):
$ datamash -W --header-in groupby 1,4 count 4 < teams.csv | awk '{print $3, $2, $1}'
1 Loss Knicks
1 Win Celtics
2 Loss Lakers
1 Win Knicks
1 Win Lakers
请注意,因为我们不要求 datamash 进行排序,这只会对已经相邻的结果进行分组。
如果你的数据确实是逗号分开然后更换 -W
经过 -t,
答案4
您可以只使用sort
然后将其通过管道输入,uniq -c
但这将包括Team, Result
.
为了避免这种情况:
$ awk 'NR>1 {print $4,$1}' team.csv | sort -k2 | uniq -c
解释每个部分:
awk 'NR>1 {print $4,$1}'
- 打印比第一行大的所有行以及结果,后跟第 4 列和第 1 列指定的球队和结果。sort -k2
- 按团队排序,awk
操作后成为第二列。uniq -c
- 计算唯一出现的次数
按团队排序的输出:
1 Win Celtics
1 Loss Knicks
1 Win Knicks
2 Loss Lakers
1 Win Lakers