我试图合并两个具有不同标头的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();
所有人都给了我相同的结果,没有快乐。
任何帮助将不胜感激。
答案 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
的结果会在到达其中一个文件的末尾时停止。