C#合并具有不同标题的CSV文件

时间:2015-12-14 15:15:27

标签: c# csv merge

我试图合并两个具有不同标头的csv文件。当我这样做时,第二个文件添加到csv文件的底部而不是#34;右边#34;它的。 例如。 文件1有标题(每列中有数据) Col A,Col B,Col C. 文件2有标题(每列中有数据) Col F,col F,Col F

在文件1中合并之后,我希望它能够阅读

col A,b,c,d,e,f

列数据

(每列中有相应的数据)但我的合并是将它添加到文件的底部,所以它读起来像

a,b,c

文件1的数据

d,e,f

文件2的数据

当我按照c#

做我想的时候
string file1 = File.ReadAllText(@"C:\file1.csv");
        string file2 = File.ReadAllText(@"C:\file2.csv");
        File.WriteAllText(@"C:\file2.csv", string.Concat(file1, file2));

File.AppendAllText(@"C:\file1.csv", file2);

或使用流阅读器

StreamWriter wtr = new StreamWriter(@"C:\file1.csv");
wtr.Write(file1 + "\t" + file2); //tried different variations with this one
wtr.Close();
wtr.Dispose();

所有人都给了我相同的结果,没有快乐。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:3)

你必须逐行加入它们,而不是一个接一个地加入它们。在框架中没有内置的方法来执行此操作,因此您必须自己编写代码。

您的主要问题是处理文件不具有相同行数的情况。如果他们保证总是有这个,那么操作相对简单。这里有一些类似C#的伪代码,它说明了天真的解决方案:

var first = File.ReadAllLines("firstfile.csv");
var second = File.ReadAllLines("secondfile.csv");
var result = first.Zip(second, (f, s) => string.Join(",", f, s));
File.WriteAllLines("combined.csv", result);

File.ReadAllLines返回一个字符串数组,每行一个。您可以通过这种方式轻松读入并将文件分成单独的行。

.Zip是一个Linq扩展方法(您必须通过在文件顶部为using添加System.Linq语句来包含它),它将两个枚举连接在一起,一个项目位于时间,像拉链一样。它将每一行传递给您提供的执行连接的函数 - 在本例中为(f, s) => string.Join(",", f, s)

string.join是一种方便的方法,用于连接由静态文本分隔的字符串。在这种情况下,文本是逗号","。它在其他情况下更有用,但我在这里使用它是因为我可以。

并且File.WriteAllLines将可枚举字符串的内容写入文件。

现在,如果你必须处理可枚举长度不同的情况,你必须逐步浏览每个集合的每一行并将它们手动连接到输出集合中,为缺失的数据添加空列。这有点复杂,但可以完成。如果你必须处理这种情况,请自己尝试一下,如果遇到问题则再回来,并从你的代码中提出一个新问题。

答案 1 :(得分:1)

尝试以下

string separator = ","; //Change this to whatever column separator you want.
var file1 = File.ReadLines(@"C:\file1.csv");
var file2 = File.ReadLines(@"C:\file2.csv");
File.WriteAllLines(@"C:\file2.csv", file1.Zip(file2, (f1, f2) => f1 + separator + f2);

首先使用File.ReadLines会导致IEnumerable<string>在迭代时会读取文件的每一行。然后,Enumerable.Zip扩展方法允许您根据每个可枚举内的相对位置连接两个枚举。最后File.WriteAllLines会迭代Zip的结果并将每一行写入您的文件。

另请注意,如果文件的行数不同,则Zip的结果会在到达其中一个文件的末尾时停止。