挑战:智能地合并CSV文件

时间:2010-03-31 14:18:03

标签: database csv

我们正在改变网店平台,我们需要从不同来源导入产品数据。

我们目前有来自不同系统/数据库的几个不同的csv文件,因为每个系统都缺少一些信息。幸运的是,产品ID是相同的,因此可以使用ID关联数据。

我们需要将这些数据合并到一个大的csv文件中,以便我们可以导入到我们的新电子商务网站。

我的问题:当您需要将csv文件与相关数据合并到一个csv文件中时,是否有一般的方法?是否有任何应用程序或工具可以帮助您解决问题?

7 个答案:

答案 0 :(得分:3)

如果您使用R,则可以加载csv文件,然后执行您喜欢的任何查询,就像使用数据库中的表一样。

例如,您可以为每个csv使用如下命令

table1 <- read.csv("D:/table1.csv", header=T, sep=",", na.strings=c(".", "NA", "", "?"))

然后加载sqldf

library(sqldf)

执行查询

table3 <- sqldf("SELECT X1, X2, X3 FROM table1 JOIN table2 USING(X1)")

最后,将结果导出为新的csv

write.csv(table3 , file = "D:/temp/table3.csv")

答案 1 :(得分:2)

是。使用Python和csv模块。

读取,创建合并的结果集,然后编写。

import csv

products = {}
with open( "one file.csv", "rb" ) as source:
    rdr = csv.DictReader( source )
    for row in rdr:
        products[row['somekeycolumn']] = row # or maybe some rearrangement

with open( 'another file.csv', 'rb' ) as source:
    rdr = csv.DictReader( source )
    for row in rdr:
        if row['adifferentkey'] in products:
            # maybe update?
        else:
            products[row['adifferentkey']] = row # or maybe some rearrangement

with open( 'result.csv', 'wb' ) as target:
    wtr = csv.writer( target ) 
    wtr.writerow( ['the','heading','columns'] )
    for name in sorted( product ) ):
        wtr.writerow( products[name] )

类似的东西。

答案 2 :(得分:2)

当然,任何能够操作文件的编程语言/工具都可以完成这项工作(Python / Perl / PHP / Ruby / awk等)。使用awk * nix工具的示例,使用字段1作为公共密钥处理2个csv文件

awk -F"," 'FNR==NR{
  d[$1]=$0
  next
}
{
  print d[$1],$0
}' file1 file2

答案 3 :(得分:2)

我写了TxtSushi来对平面文件文件进行SQL选择和其他一些简单的转换。例如,您可以执行以下操作:

tssql -table t1 tbl1.csv -table t2 tbl2.csv \
'select * from t1 inner join t2 on t1.id=t2.id'

有很多example scripts here。它在http://hackage.haskell.org上作为一个包分发,因此安装取决于the Haskell Platform

答案 4 :(得分:1)

为什么不将每个csv文件加载到公共输入表中,然后使用SQL从那里合并到永久表中。样本输入表:

InputCSVFiles
FileID     int PK auto number/identity
FileName   string
FileHash   string

InputCVSItems
ItemID     int PK auto number/identity
FileID     FK
ProductID
Col1
Col2
...
只需将每个文件加载到表中,就可以使用文件哈希来防止重复文件上传。然后,您可以使用SQL来标识重复项,并根据需要使用SQL将SELECT插入到永久表中。我不确定有多少重复的产品,但是使用自联接,COALESCE(),ROW_NUMBER(),GROUP BY,MIN()等在SQL中处理它们相当容易。

INSERT INTO Product
        (ProductID, col1, col2, ...)
    SELECT
        ProductID, col1, col2, ...
        FROM InputCVSItems
        ...

答案 5 :(得分:0)

一旦我写了"dsv2sql" utility,就完全符合你的需要。这是一个示例命令:

./dsv2sql --delimiter=, --output=csv --uid=id one.csv two.csv > combined_one_two.csv

自然会输入带有标题的CSV文件。

答案 6 :(得分:0)

这是一个CVS-Merge实用程序,它可以选择仅在合并时比较列范围,并通过检测重叠或仅添加唯一行来支持合并。