如何在Java中合并CSV文件
我的第一个csv文件看起来像这样包含标题(标题仅包含在顶部而不是每个条目之后):
NAME,SURNAME,AGE Fred,Krueger,Unknown .... n records
我的第二个文件可能如下所示:
NAME,MIDDLENAME,SURNAME,AGE Jason,Noname,Scarry,16 .... n records with this header template
合并的文件应如下所示:
NAME,SURNAME,AGE,MIDDLENAME Fred,Krueger,Unknown, Jason,Scarry,16,Noname ....
基本上,如果标头不匹配,则应根据该顺序在原始标头及其值之后添加所有新标题标题(列)。
更新:
上面的CSV变得更小,所以我可以说明我想要实现的目标,实际上CSV文件是在此之前生成的一步(合并),最多可以是100列
有谁知道我该怎么做? 我很感激任何帮助
我将为’更大’格式创建一个模型(一个包含四个字段的简单类和一个用于此类实例的集合)并实现两个解析器,一个用于第一个,一个用于第二个模型。 为两个csv文件的所有行创建记录,并实现编写器以正确的格式输出csv。 简单来说:
public void convert(File output, File...input) { List records = new ArrayList (); for (File file:input) { if (input.isThreeColumnFormat()) { records.addAll(ThreeColumnFormatParser.parse(file)); } else { records.addAll(FourColumnFormatParser.parse(file)); } } CsvWriter.write(output, records); }
从你的评论我看到,你有很多不同的csv格式与一些常见的列。
您可以为各种csv文件中的任何行定义模型,如下所示:
public class Record { Object id; // some sort of unique identifier Map values; // all key/values of a single row public Record(Object id) {this.id=id;} public void put(String key, String value){ values.put(key, value); } public void get(String key) { values.get(key); } }
要解析任何文件,首先要读取标题并将列标题添加到全局密钥库(稍后将需要输出),然后为所有行创建记录,如:
//... List records = new ArrayList () for (File file:getAllFiles()) { List keys = getColumnsHeaders(file); KeyStore.addAll(keys); // the store is a Set for (String line:file.getLines()) { String[] values = line.split(DELIMITER); Record record = new Record(file.getName()+i); // as an example for id for (int i = 0; i < values.length; i++) { record.put(keys.get(i), values[i]); } records.add(record); } } // ...
现在密钥库都使用了列标题名称,我们可以迭代所有记录的集合,获取所有键的所有值(如果此记录的文件没有使用密钥,则获取null
),汇编csv行并写入一切都是新文件。
读入第一个文件的标题并创建列名列表。 现在读取第二个文件的标题,并将列表中已存在的任何列名称添加到列表的末尾。 现在,您按照所需的顺序排列列,然后可以先将其写入新文件。
接下来我将解析每个文件,对于每一行,我将创建一个列名为Map的Map。 解析完行后,您可以遍历新的列名列表并从地图中提取值并立即将它们写入新文件。 如果值为null,则不打印任何内容(如果需要,只显示逗号)。
可能有更高效的解决方案,但我认为这符合您的要求。
尝试这个:
http://ondra.zizka.cz/stranky/programovani/ruzne/querying-transforming-csv-using-sql.texy
crunch input.csv output.csv "SELECT AVG(duration) AS durAvg FROM (SELECT * FROM indata ORDER BY duration LIMIT 2 OFFSET 6)"