在csv文件中查找模式

在csv文件中查找模式,csv,awk,Csv,Awk,尝试根据重复行对csv文件进行排序 awk -F, 'NR>1{arr[$4,",",$5,",",$6,,",",$7,",",$8,",",$9]++}END{for (a in arr) printf "%s\n", arr[a] "-->" a}' test.txt 输入文件 a,b,d,1,2,3,4,5,6,y,x,z k,s,t,1,2,3,4,5,6,t,z,s a,b,k,1,4,5,5,5,6,k,r,s 使用创建一个文件 a,b,d,1,2,3,4,5,6

尝试根据重复行对csv文件进行排序

awk -F, 'NR>1{arr[$4,",",$5,",",$6,,",",$7,",",$8,",",$9]++}END{for (a in arr) printf "%s\n",  arr[a] "-->" a}' test.txt
输入文件

a,b,d,1,2,3,4,5,6,y,x,z
k,s,t,1,2,3,4,5,6,t,z,s
a,b,k,1,4,5,5,5,6,k,r,s
使用创建一个文件

a,b,d,1,2,3,4,5,6,y,x,z-->2
k,s,t,1,2,3,4,5,6,2,t,z,s-->2
a,b,k,1,4,5,5,5,6,1,k,r,s-->1
  • 其中,最后一列包含从第4位开始到第9位的数字模式的出现次数
对重复行进行计数和排序

我已经知道了计数的模式,但我不知道如何将其余的列添加到行中:


感谢您的支持。

一种数据读取两次的解决方案,第一次读取重复数据,第二次输出:

$ awk -F, '
NR==FNR {
    a[$4 ORS $5 ORS $6 ORS $7 ORS $8 ORS $9]++              # count
    next
}
{
    print $0 "-->" a[$4 ORS $5 ORS $6 ORS $7 ORS $8 ORS $9] # output
}' file file
a,b,d,1,2,3,4,5,6,y,x,z-->2
k,s,t,1,2,3,4,5,6,t,z,s-->2
a,b,k,1,4,5,5,5,6,k,r,s-->1

您也可以尝试Perl。该文件只读取一次,因此速度会更快。看看这个:

$ cat shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z
k,s,t,1,2,3,4,5,6,t,z,s
a,b,k,1,4,5,5,5,6,k,r,s
$ perl -F, -lane ' $v=join(",",@F[3..8]);$kv{$_}{$v}=$kv2{$v}++; END { while(($x,$y)=each (%kv)){ while(($p,$q)=each (%{$y})) { print "$x --> $kv2{$p}" }}}' shimon.txt
a,b,k,1,4,5,5,5,6,k,r,s --> 1
a,b,d,1,2,3,4,5,6,y,x,z --> 2
k,s,t,1,2,3,4,5,6,t,z,s --> 2
$
另一个较短的Perl代码

$ perl -F, -lane ' $kv{$_}=$kv2{join(",",@F[3..8])}++; END { for(keys %kv) { $t=join(",",(split /,/)[3..8]); print "$_ --> $kv2{$t}" } } ' shimon.txt
a,b,k,1,4,5,5,5,6,k,r,s --> 1
a,b,d,1,2,3,4,5,6,y,x,z --> 2
k,s,t,1,2,3,4,5,6,t,z,s --> 2


请您尝试以下操作,只读取一次输入文件

awk '
BEGIN{
  FS=OFS=","
}
{
  a[FNR]=$0
  b[FNR]=$4 FS $5 FS $6 FS $7 FS $8 FS $9
  c[$4 FS $5 FS $6 FS $7 FS $8 FS $9]++
}
END{
  for(i=1;i<=FNR;i++){
    print a[i]" ---->" c[b[i]]
  }
}'  Input_file
awk'
开始{
FS=OFS=“,”
}
{
a[FNR]=0美元
b[FNR]=$4财政司司长$5财政司司长$6财政司司长$7财政司司长$8财政司司长$9
c[$4财政司司长$5财政司司长$6财政司司长$7财政司司长$8财政司司长$9]++
}
结束{

对于(i=1;iJames Brown的答案是一个非常简单的双过程解决方案,它的优点是不需要将文件存储到内存中,但缺点是必须读取一个文件两次。下面的解决方案正好相反,只读取一个文件,但必须将其保存到内存中。为此,我们需要3个数组。数组
c
要跟踪计数,请使用数组
b
作为缓冲区,使用数组
a
跟踪原始顺序

此外,我们将使用多维数组索引:

有效的数组索引应由一个或多个分隔的表达式组成,类似于某些编程语言中多维数组的索引方式。由于awk数组实际上是一维的,因此这种分隔的列表应通过将每个单独表达式的字符串值串联起来转换为单个字符串通过
subsp
变量的值与另一个分开。因此,以下两个索引操作应等效:

var[expr1, expr2, ... exprn]
var[expr1 SUBSEP expr2 SUBSEP... SUBSEP exprn]
现在的解决方案是:

{ a[NR] = $4 SUBSEP $5 SUBSEP $6 SUBSEP $7 SUBSEP $8 SUBSEP $9
  b[$4,$5,$6,$7,$8,$9] = $0
  c[$4,$5,$6,$7,$8,$9]++ }
END { for(i=1;i<=NR;++i) print b[a[i]],"-->",c[a[i]] }
{a[NR]=$4分包$5分包$6分包$7分包$8分包$9
b[$4、$5、$6、$7、$8、$9]=$0
c[$4、$5、$6、$7、$8、$9]+}

END{for(i=1;i因为问题类似于SQL模式,所以也可以使用sqlite

$ cat shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z
k,s,t,1,2,3,4,5,6,t,z,s
a,b,k,1,4,5,5,5,6,k,r,s
$ cat sqllite_cols4_to_9.sh
#!/bin/sh
sqlite3 <<EOF
create table data(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12);
.separator ','
.import "$1" data
select t1.*, " --> " || t2.cw from data t1, ( select c4,c5,c6,c7,c8,c9, count(*) as cw from data group by c4,c5,c6,c7,c8,c9 ) t2
where t1.c4=t2.c4 and t1.c5=t2.c5 and t1.c6=t2.c6 and t1.c7=t2.c7 and t1.c8=t2.c8 and t1.c9=t2.c9;
EOF
$ ./sqllite_cols4_to_9.sh shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z, --> 2
k,s,t,1,2,3,4,5,6,t,z,s, --> 2
a,b,k,1,4,5,5,5,6,k,r,s, --> 1
$
$cat shimon.txt
a、 b,d,1,2,3,4,5,6,y,x,z
k、 s,t,1,2,3,4,5,6,t,z,s
a、 b,k,1,4,5,5,6,k,r,s
$cat sqllite_cols4_至_9.sh
#!/bin/sh
SQLITE32
k、 s,t,1,2,3,4,5,6,t,z,s,-->2
a、 b,k,1,4,5,5,6,k,r,s,-->1
$

那么,最后一列中的数字是什么,计数还是订单号?最后一列是-->count请定义排序参与的模式的概念?首先,您似乎有一些问题
$4,“,”,$5,“,$6,,
。它们也是不需要的。您创建的索引将读取
$4@,@“$5@”…
。这可能不是您想要的。不,不是这样。一些神秘的数字可能会出现在操作预期输出的第10列中。我不太理解它们。让我检查:-)最后的文件文件是可以处理的多个文件?抱歉-我运行了它-在运行命令后没有发生任何事情-当我删除单词“next”时,它会显示一个结果-但不准确:NR==FNR{a[$4$5$6$6$7$8$9]+}{print$0”->“a[$4$5$6$8$9]}”测试A、B、D、1,2、3、4、5、6、Y、X、Z>1 K、S、T、1、2、3、4、5、6、T、Z、S->2 A、B、K、1、4、5、5、6、K、R、S>1。第一行也应该被认为是2高兴听到。请考虑接受答案。
$ cat shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z
k,s,t,1,2,3,4,5,6,t,z,s
a,b,k,1,4,5,5,5,6,k,r,s
$ cat sqllite_cols4_to_9.sh
#!/bin/sh
sqlite3 <<EOF
create table data(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12);
.separator ','
.import "$1" data
select t1.*, " --> " || t2.cw from data t1, ( select c4,c5,c6,c7,c8,c9, count(*) as cw from data group by c4,c5,c6,c7,c8,c9 ) t2
where t1.c4=t2.c4 and t1.c5=t2.c5 and t1.c6=t2.c6 and t1.c7=t2.c7 and t1.c8=t2.c8 and t1.c9=t2.c9;
EOF
$ ./sqllite_cols4_to_9.sh shimon.txt
a,b,d,1,2,3,4,5,6,y,x,z, --> 2
k,s,t,1,2,3,4,5,6,t,z,s, --> 2
a,b,k,1,4,5,5,5,6,k,r,s, --> 1
$