按列和值比较两个 csv 文件,并显示不同值的行号

本文关键字:显示 文件 两个 比较 csv | 更新日期: 2023-09-27 17:55:28

我正在为两个具有列和相应值的 csv 文件做比较器对于每个新行上的每一列。列在文件的第一行指定。之后的每一行都包含每列的数据。

我正在尝试创建一个程序,该程序可以处理具有不同行号和列数的文件,

并且还可以显示不同值的行号,然后创建一个新的文本文件,显示行号,列名和文件1和文件2的值。

比较应基于某些标识符而不是逐行进行比较。如果缺少列行中指定的某些列数据,则它可以显示缺少数据的列数。

所以例如:
工人1.csv:

名字;年龄;高度;性;
鲍勃;21;190;雄
约翰福音;35;182;雄
玫;
玛丽;20;175;女性

工人2.csv

名字;年龄;高度;性
鲍勃;21;185;雄
约翰福音;30;186;雄
玛丽;

输出.csv

在玛丽身上发现的差异:
文件 2,第 3 行,缺少三个值
在鲍勃中发现的差异:
文件 1,第 1 行,高度:190
文件 2,第 1 行,高度:185
在约翰身上发现的差异:
文件 1,第 2 行,年龄:35,身高:182
文件 2,第 3 行,年龄:30,身高:186

我应该怎么做?我确实在两个文件行上查看了 LINQ 的 Except ,但我如何获取行号?

按列和值比较两个 csv 文件,并显示不同值的行号

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

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

您要做的第一件事是将其中一个文件加载到字典中,按 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
}

从两个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
}