如何在 csv 或 txt 中查找缺失的行? (复杂的)

How to find missing row in csv or txt? (Complicated)

这是例子...

文件 1:

1;01812345;BB100

2;018ACBA5;BB100

3;01955555;BB100

10;01901022;BB100

文件 2:(mac 地址不同,缺少 3 个;)

1;01866666;BB101

2;01877777;BB101

10;01988888;BB101

如何快速确定我失踪了3;?我无法比较整行,因为我只需要比较第一个 ;

之前的第一个整数值

我需要一些自动化的解决方案,因为我使用 300 个地址的列表并且它不是连续的。

  1. 为每个文件创建一个副本。
  2. 去掉分号后面的部分,用正则表达式替换:
    • 查找内容;.*$
    • 替换为:(留空)
    • 勾选左下角的**正则表达式*
    • 点击全部替换
  3. 对每个副本进行排序(编辑 -> 生产线操作 -> 排序)。
    • 也许排序后您可以通过查看文件找到额外的行,否则继续下一步。
  4. 比较排序后的版本:差异 给出了一个或另一个文件(原始未排序文件)中的行。有几个选项可以自动进行比较:
    • 有一个名为 Compare 的记事本++插件,您可以通过插件管理器安装它
    • 您可以使用单独的程序,例如 winmerge
  5. 一旦知道该行,就可以查找缺失的行并将其添加到其他文件

另一种选择是将两个文件的行插入到一个新文件中,然后对新文件进行排序。现在您需要在第一列中找出具有唯一编号的行。但我会使用比较工具或如上所述的比较插件。它使差异更容易发现。

你在我的另一个回答的评论中说,这个任务是你经常做的事情,你也表达了自动化的愿望。这是一个小的 C++ 程序,它应该可以工作:像 prg file1 file2 一样使用它来从文件 1 中查找文件 2 中缺少的键的行。要获取 file1 中缺少的行,请切换参数的顺序:prg file2 file1.

#include <iostream>
#include <string>
#include <map>
#include <fstream>

using namespace std;

typedef map< string, string > tMap;

bool readFileIntoMap( string fn, tMap &m) 
{
    ifstream inFile( fn, std::ios::in);
    if( !inFile.good() ){
        std::cout << "Could not open " << fn << std::endl;
        return false;
    }

    string key, aLine;
    string::size_type pos;
    while ( inFile ) {
        getline( inFile, aLine ) ;

        pos = aLine.find( ';' );
        if( pos != string::npos ) {
            key = aLine.substr(0, pos);
        } else {
            key = "-1";
        }

        m[ key ] = aLine; // map key to complete line
    } // of while
    return true;
}

// check for each key of first file: if the key is present in the
// second file, if not: report the line from the first file 
void findMissingKeys( tMap &leftMap,  tMap &rightMap)
{
    string leftKey;
    for( auto &leftElem : leftMap) {
        leftKey = leftElem.first;

        auto it =  rightMap.find( leftKey );
        if( it == rightMap.end() ) {
            // report missing line in second file
            cout << leftElem.second << endl;
        }
    }
}

int main( int argc, char* argv[] ) {
    if ( argc != 3 ) {
        cerr << "Please provide exactly two filenames as argument!" << endl;
        cerr << "Program will dump lines with a key present in first and missing in second file." << endl;
        return 1;
    }

    tMap m1, m2;

    readFileIntoMap( argv[1], m1 );
    readFileIntoMap( argv[2], m2 );

    findMissingKeys(m1,m2);
}