在 csv 文件中查找字段模式,然后计算唯一字段值

在 csv 文件中查找字段模式,然后计算唯一字段值

我正在使用 Cygwin (bash) 创建一个脚本来查找、分组和计算多个 CSV 文件中的字段。每行都有以逗号分隔的字段,每个字段都遵循类似的约定。先有一个数字值,然后是一个等号 (=),然后是一个字母数字值。 “(number)=”可能会或可能不会出现在一行中,如果出现,字段位置可能会有所不同,但在行中仅出现一次。另外,等号后面的值的长度也会有所不同。

我的目标的一个例子是最好的。 CSV 文件:

35=D,11=ABCD1,1=ABC,55=XYZ,38=100,40=P,18=M,54=1,59=0,10=111
35=D,11=ABCD2,1=ABC,55=XYZ,38=200,40=P,18=M,54=1,44=10.00,59=0,10=133
35=D,11=ABCD3,1=ABC,55=XYZ,38=300,40=P,18=M B,54=1,44=10.00,59=0,110=200,10=113
35=D,11=ABCD4,1=ABC,55=XYZ,38=400,40=P,18=M B F,54=1,44=10.00,59=0,110=300,10=144
35=D,11=ABCD5,1=ABC,55=ZYX,38=300,40=2,54=1,44=10.00,59=3,10=132
35=D,11=ABCD6,1=ABC,55=QQQ,38=100,40=1,18=C,54=2,59=3,10=131

“18=”字段值以空格分隔。我想要一个脚本或单行代码来识别每个唯一的“18=”值,然后计算每个值的出现次数。使用上述文件的输出将是(排序是可选的):

18=M 2
18=M B 1
18=M B F 1
18=C 1

如前所述,此脚本应读取许多包含此格式记录的文件。我尝试过不同的grep组合并涉足awk,但我不太熟悉它的正确实现。

前两个答案确实有效(非常感谢!)。是否可以扩展以聚合按唯一“18=”计数结果分组的“38=”值?

答案1

这可能最好在 Perl 中使用哈希结构来完成:

perl -nle '($x)=/(18=[^,]+)/;$y{$x}++; END{print "$_ $y{$_}" for keys %y}' files

解释

对于每一行,Perl 都会查找18=后面尽可能多的非逗号字符;无论找到什么,它都会存储在变量 中$x。然后,该变量用作 hash 的键%y,其关联值会随着$x找到的每个键而递增。

在最ENDIE,在处理完所有行之后),我们打印18=...哈希变量的键(字段)和关联值(出现次数)%y

答案2

你尝试一下这个组合吗?

grep -ho "18=[^,]*" list_of_files | sort | uniq -c

相关内容