使用AWK根据某些列获取记录文件的唯一计数

时间:2017-09-07 16:28:44

标签: shell unix awk

我有一个AWK命令来修改以获得基于主键的记录文件的唯一计数。在记录文件中,有21个元素,第1列和第18列是PK。记录全部在一行,记录分隔符为\ ^,字段分隔符为|。这是我到目前为止所得到的,但它仍然给我文件中的总记录数,但不是唯一的:

awk 'BEGIN{RS="\\^";FS="\\|";} {a[ $1  $18 ]++;}END{print length(a);}' filename

示例数据:

1|01212121|0|OUTGOING| | | | | |57 OHARE DR|not available|DALLAS|TX|03560|US|1131142334825|1|Jan 15 2004 11:12:06:576AM|Jan 15 2004  2:54:41:226PM|SYSTEM|\^

这类数据有200万行,我有30个重复数据。

预期产出应为:1999970

2 个答案:

答案 0 :(得分:1)

将GNU awk用于多字符RS并在数组索引组件字段之间使用SUBSEP以使结果唯一:

awk 'BEGIN{RS="\\^"; FS="|"} NF>1{a[$1,$18]} END{print length(a)}' filename

如果输入文件/行以NF>1结尾而不仅仅是\^\n,则需要\n测试。我们知道它确实以\n结尾,因为您说if I do a wc -l on the file, it will return 1wc -l只计算\n s并且您的1个样本输入行以\^结尾,以便所有潜在客户我相信您的文件以\^\n结尾,因此必须对NF>1进行测试,以避免在最终\^之后包含空白记录。

答案 1 :(得分:0)

至少记录分隔符RS只能容纳一个字符。由于everthing在一行中拥塞,您需要选择数据行的最后一个字符作为RS并丢弃最后一个字段(由\组成)。 修复如下:

awk 'BEGIN{RS="^";FS="|"} {a[$1,$18]++} END{print length(a)}' filename

请注意,awk现在将在输入中遇到的每个^上拆分。如果您需要仅在\^上拆分,则建议如下:

sed 's/\\^/\n/g' filename |awk 'BEGIN{FS="|"} {a[$1,$18]++} END{print length(a)}'

修改 来自@Ed。

的评论