这是我能够在 BC4 中完成所需行为的方式。
BC 支持在打开文件进行比较时运行“预处理器”应用程序。所以我所做的是制作一个简单的可执行文件,它需要 3 个参数(argv[]):
- 原始文件的路径
- 已处理文件的路径(最终将由 BC 打开以进行比较)
- 包含行分隔的搜索子字符串的 txt 文件的路径(更多内容见下文)
上面的第 3 项只能包含一个条目(使用与原始问题相同的示例),例如"transactionType: 6"。然后,可执行文件在原始文件(上面的第 1 项)的每一行中搜索上面第 3 项中定义的搜索子字符串。每次命中时,整行都被复制(附加)到输出文件中(上面的第 2 项)。
接下来,您需要在 BC 中定义文件格式(在 Mac 上,您转到Beyond Compare菜单并单击File Formats...)。选择文件的扩展名,然后单击转换选项卡。使用下面的屏幕截图作为示例。注意:%s由 BC 定义,指的是原始文件(第 1 项)的路径, %t指的是处理后的文件(第 2 项)的路径。
截屏
因此,当您打开File1.txt和File2.txt进行比较时,BC 将调用您的可执行文件(每个执行一次),然后打开生成的文件(第 2 项)。这将有效地显示两个文件的“过滤”版本,仅显示包含搜索子字符串的行。
另请注意,%t参数将是 BC 内部生成的某种临时路径。
下面是上述可执行文件的快速实现:
#include <iostream>
#include <fstream>
#include <list>
using namespace std;
int main(int argc, const char * argv[])
{
ifstream inputFile (argv[1]);
ifstream substringFile (argv[3]);
ofstream outputFile;
outputFile.open(argv[2]);
//build the list of substrings from the substring input file
list<string> substringList;
string line;
//TODO: make this safer
while (getline(substringFile, line))
{
substringList.push_back(line);
}
//for each substring in the list
for (list<string>::const_iterator iter = substringList.begin(); iter != substringList.end(); iter++)
{
if (inputFile.is_open())
{
//for all the lines in the file
while (getline(inputFile, line))
{
//Find the current substring
if (line.find(*iter) != string::npos)
{
outputFile << line << "\n";
}
}
}
//go back to the beginning of the file
inputFile.clear();
inputFile.seekg(0, ios::beg);
}
inputFile.close();
outputFile.close();
return 0;
}
希望这可以帮助!