按列和值比较两个csv文件并显示不同值的行号[关闭]

问题描述 投票:0回答:2

我正在为两个 CSV 文件编写一个比较器脚本,其中每个新行上都有列和每列的相应值。列在文件的第一行指定。之后的每一行都包含每列的数据。文件以分号分隔。

我正在尝试创建一个程序,该程序可以处理具有不同行号和列数的文件,并且还可以显示不同值的行号,然后创建一个新的文本文件,显示行号、列名和文件 1 和文件 2 的值。

比较应该基于一些标识符而不是逐行进行。如果列行中指定的某些列数据丢失,那么它可以显示丢失数据的列数。

举个例子:

worker1.csv:

姓名 年龄 高度 性别
鲍勃 21 190
约翰 35 182
玫瑰
玛丽 20 175

worker2.csv

姓名 年龄 高度 性别
鲍勃 21 185
约翰 30 186
玛丽

输出.csv

Differences found in Mary:  
File 2, Line number 3, Missing three values  
Differences found in Bob:  
File 1, Line number 1, Height: 190  
File 2, Line number 1, Height: 185      
Differences found in John:  
File 1, Line number 2, Age: 35, Height: 182  
File 2, Line number 3, Age: 30, Height: 186

我该怎么做?我确实在两个文件行上研究了 LINQ 的 except,但是如何获取行号?

c# linq csv
2个回答
4
投票

这比第一次出现时要复杂一些。但如果你一步一步地去做,这是可行的。

我假设您有足够的内存将文件的记录之一加载到字典中。如果您的文件非常大,事情就会变得更加复杂。

您要做的第一件事是将其中一个文件加载到字典中,并按 ID 进行索引。在我的示例中,我假设 ID 就是名称。每条记录都会记录在一个

FileLine
实例中:

class FileLine
{
    public int LineNumber;
    public string Name;
    public int Age;
    public int Height;
    public string Gender;
}

还有你的字典:

Dictionary<string, FileLine> File1Lines = new Dictionary<string, FileLine>();

现在,将文件读入该字典:

int lineNumber = 0;
foreach (var line in File.ReadLines("worker1.csv")
{
    // split the line and assign the fields.
    // End up with name, age, height, and gender variables.
    ++lineNumber;
    var theLine = new FileLine(
        LineNumber = lineNumber,
        Name = name,
        Age = age,
        Height = height,
        Gender = gender);
    File1Lines.Add(theLine.Name, theLine);
}

现在,您可以读取第二个文件,在字典中查找该项目,并报告任何差异:

lineNumber = 0;
foreach (var line in File.ReadLines("worker2.csv"))
{
    // split the line and create a FileLine instance.
    // we'll call it line2
    // Then, look to see if that line is in the File1Lines dictionary.
    FileLine line1;
    if (!File1Lines.TryGetValue(line2.Name, out line1))
    {
        // the line didn't exist in the first file
    }
    else
    {
        // Now compare individual fields
        if (line2.Age != line1.Age)
        {
            // report that fields are different
        }
        // Do the same with other fields
    }
}

现在,如果您想跟踪第一个文件中但不在第二个文件中的行,则创建一个

HashSet<string>
,每当您在第二个文件中找到记录时,请将名称添加到哈希集中。完成第二个文件后,您可以将哈希集与字典中的键进行比较。因此,如果您的哈希集称为
FoundRecords
,那么您将拥有:

var recordsNotFound = File1Lines.Keys.Except(FoundRecords);
foreach (var name in recordsNotFound)
{
    // look up item in the dictionary to report not found
}

0
投票

从两个foreach循环中,你可以发现差异,或者使用for循环也可以:

string[] content1 = File.ReadAllLines(@"worker1.csv");
string[] content2 = File.ReadAllLines(@"worker2.csv");
for(int i = 0; i < content1.Length; i++)
{
  // check here every line, i is your line number
}
for(int i = 0; i < content2.Length; i++)
{
  // check here every line, i is your line number
}
© www.soinside.com 2019 - 2024. All rights reserved.