Bash 基于csv中特定比较列数的行高级连接

Bash 基于csv中特定比较列数的行高级连接,bash,csv,awk,sed,compare,Bash,Csv,Awk,Sed,Compare,这是基于已解决问题的问题。 我有以下类型的.csv文件它们不都排序!,但立柱的结构是相同的: name1,address1,town1,zip1,email1,web1,,,,category1 name2,address2,town2,zip2,email2,,,,,category2 name3,address3,town3,zip3,email3,,,,,category3_1 name3,address3,town3,zip3,,,,,,category3_2 name3,address

这是基于已解决问题的问题。 我有以下类型的.csv文件它们不都排序!,但立柱的结构是相同的:

name1,address1,town1,zip1,email1,web1,,,,category1
name2,address2,town2,zip2,email2,,,,,category2
name3,address3,town3,zip3,email3,,,,,category3_1
name3,address3,town3,zip3,,,,,,category3_2
name3,address3,town3,zip3,,,,,,category3_3
name4,address4,town4,zip4,,,,,,category4_1
name4,address4,town4,zip4,email4,,,,,category4_2
name4,address4,town4,zip4,email4,,,,,category4_3
name4,address4,town4,zip4,,,,,,category4_4
name5,address5,town5,zip5,,,,,,category5_1
name5,address5,town5,zip5,,web5,,,,category5_2
name6,address6,town6,zip6,,,,,,category6
列中的前4个记录始终填充,其他列不总是填充,最后一个除外-类别 分隔符之间的空格表示没有特定行或名称的数据 如果nameX不包含addressX,但包含addressY,则它是一个不同的记录,不在同一行中,不应连接 我需要sed或awk中的脚本,可能是bash,但是这个解决方案在更大的文件[数百MB+]上稍微慢一点,这将占用前4列。在本例中,比较它们,如果匹配,将合并每个类别与;分隔符,并将结构和最可能的数据保留在.csv文件中匹配行的其他列中:

name1,address1,town1,zip1,email1,web1,,,,category1
name2,address2,town2,zip2,email2,,,,,category2
name3,address3,town3,zip3,email3,,,,,category3_1;category3_2;category3_3
name4,address4,town4,zip4,email4,,,,,category4_1;category4_2;category4_3;category4_4
name5,address5,town5,zip5,,web5,,,,category5_1;category5_2
name6,address6,town6,zip6,,,,,,category6
如果这是不可能的,解决方案可能是保留来自复制数据的第一行的数据,即具有categoryX_1的数据。例如:

name1,address1,town1,zip1,email1,web1,,,,category1
name2,address2,town2,zip2,email2,,,,,category2
name3,address3,town3,zip3,email3,,,,,category3_1;category3_2;category3_3
name4,address4,town4,zip4,,,,,,category4_1;category4_2;category4_3;category4_4
name5,address5,town5,zip5,,,,,,category5_1;category5_2
name6,address6,town6,zip6,,,,,,category6
在使用脚本之前,是否必须对.csv进行排序

再次感谢你

sed -n 's/.*/²&³/;H
$ { g
:cat
  s/\(²\([^,]*,\)\{4\}\)\(\([^,]*,\)\{5\}\)\([^³]*\)³\(.*\)\n\1\(\([^,]*,\)\{5\}\)\([^³]*\)³/\1~\3~ ~\7~\5;\9³\6/
  t fields
  b clean
:fields
  s/~\([^,]*\),\([^~]*~\) ~\1,\([^~]*~\)/\1,~\2 ~\3/
  t fields
  s/~\([^,]*\),\([^~]*~\) ~\([^,]*,\)\([^~]*~\)/\1\3~\2 ~\4/
  t fields
  s/~~ ~~//g

  b cat

:clean
  s/.//;s/[²³]//g
  p
  }' YourFile
Posix版本so-使用GNU的Posix,以前没有对文件进行排序

2在缓冲区中加载完整文件后进行递归循环,添加标记以便于操作,并通过sed组替换获得很多乐趣,希望达到最大可用组数

循环以在另一行之后添加类别1行,每行每个字段上的下一个循环需要一个大的子字段临时结构化2组字段(来自2条连续行)。字段5至9为1组 将子字段解组到原始位置 最后,删除标记和第一个新行

假设没有字符,因为用作标记,您可以使用其他标记并使用新标记调整脚本

注:

对于在100 MB文件上的性能,我想awk将更加高效。 预先对数据进行排序肯定有助于降低性能,减少每个类别循环之后要处理的数据量
我发现,通过db处理这个特定问题的速度更快


db:mysql-through-wamp

如果列的数量会改变,我需要改变哪些数字?我想是4、5和9?是这样吗?非常感谢。另一件事-脚本几乎工作完美,它只是复制您的组字段5到9。。。它与作为标记的特殊字符有什么关系吗?对于字段的数量,直到在文件中始终是相同的,没有问题。调整\{4\}和\{5\}应该足够了。对于复制,没有看到我在AIX上测试的结果,但在本例中,它严重依赖于第三个标记~和字段分隔符。它复制在相对位置组装的两行的内容。如果L1F5=Hello和L2F5=World,F5的结果将是HelloWorld这是我得到的输出:名称1,地址1,城镇1,zip1,电子邮件1,网络1,,,类别1名称2,地址2,城镇2,zip2,电子邮件2,,,,,,,类别2名称3,地址3,城镇3,zip3,电子邮件3,,,,,,,,类别3\u 1;类别3_3;类别3_2姓名4、地址4、城镇4、zip4、电子邮件4、电子邮件4、、、、类别4_1;类别4_4;类别4_3;类别4_2名称5,地址5,镇5,zip5,web5,,,类别5_1;类别你能看到被复制的电子邮件吗?这是同样的问题,我得到的真实数据以及。。。如果是~char的问题,我应该将它们中的哪一个更改为其他特殊字符?在ubuntu14.04上运行与~:-这不是一个问题,我必须更改代码并添加一个检查数据是否相同,而不是重复它。如果出现两种不同的信息,如email4,会怎么样_1@lazy.dog和电子邮件4_2@brown.fox ?