如何在 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 个地址的列表并且它不是连续的。
- 为每个文件创建一个副本。
- 去掉分号后面的部分,用正则表达式替换:
- 查找内容:
;.*$
- 替换为:(留空)
- 勾选左下角的**正则表达式*
- 点击全部替换
- 对每个副本进行排序(编辑 -> 生产线操作 -> 排序)。
- 也许排序后您可以通过查看文件找到额外的行,否则继续下一步。
- 比较排序后的版本:差异 给出了一个或另一个文件(原始未排序文件)中的行。有几个选项可以自动进行比较:
- 有一个名为 Compare 的记事本++插件,您可以通过插件管理器安装它
- 您可以使用单独的程序,例如 winmerge
- 一旦知道该行,就可以查找缺失的行并将其添加到其他文件
另一种选择是将两个文件的行插入到一个新文件中,然后对新文件进行排序。现在您需要在第一列中找出具有唯一编号的行。但我会使用比较工具或如上所述的比较插件。它使差异更容易发现。
你在我的另一个回答的评论中说,这个任务是你经常做的事情,你也表达了自动化的愿望。这是一个小的 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);
}
这是例子...
文件 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 个地址的列表并且它不是连续的。
- 为每个文件创建一个副本。
- 去掉分号后面的部分,用正则表达式替换:
- 查找内容:
;.*$
- 替换为:(留空)
- 勾选左下角的**正则表达式*
- 点击全部替换
- 查找内容:
- 对每个副本进行排序(编辑 -> 生产线操作 -> 排序)。
- 也许排序后您可以通过查看文件找到额外的行,否则继续下一步。
- 比较排序后的版本:差异 给出了一个或另一个文件(原始未排序文件)中的行。有几个选项可以自动进行比较:
- 有一个名为 Compare 的记事本++插件,您可以通过插件管理器安装它
- 您可以使用单独的程序,例如 winmerge
- 一旦知道该行,就可以查找缺失的行并将其添加到其他文件
另一种选择是将两个文件的行插入到一个新文件中,然后对新文件进行排序。现在您需要在第一列中找出具有唯一编号的行。但我会使用比较工具或如上所述的比较插件。它使差异更容易发现。
你在我的另一个回答的评论中说,这个任务是你经常做的事情,你也表达了自动化的愿望。这是一个小的 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);
}