1

I am trying to compare two log files containing a list of transactions. The fields of these transactions are defined within the line itself. eg:

    transactionID: 1, transactionType: 6, transactionData: 123456
    transactionID: 2, transactionType: 6, transactionData: 654321

In one log file, transactionType 6 transactions may come consecutively, while in the other file they may be interlaced with other transaction types. So while transactionID may be different, they would still be in the same order and contain the same data.

How can I filter or otherwise only show the lines in both files which contain the string "transactionType: 6"? This would filter out all the other transactions and allow me to see only the ones with Type 6.

Thank you.

omouri
  • 15
  • 1
  • 6

2 Answers2

1

What you are asking is not possible in Beyond Compare 4.1.1 (current version).

The closest you can get to what you're describing is to only display differences within text matching a specific string.

Define a regular expression grammar element that matches on ".transactionType: 6." using the Define Unimportant Text in Beyond Compare instructions.

After you've defined the grammar element, click the Rules toolbar button (referee icon). In the Importance tab, check the box next to your new grammar element and uncheck all other grammar elements to make them unimportant. This will only highlight differences in lines that match the grammar element you defined.

Chris Kennedy
  • 2,639
  • 12
  • 11
  • Thank you for the post. It taught me a couple of things but unfortunately does not fulfill my need. I need all the lines not containing the string (or not matching the regex) to be **hidden**, and only show the lines which contain a matching expression. What you have described is how to only compare lines that contain a matching expression. – omouri Sep 24 '15 at 20:28
  • The issue is that transactions of the same type may come at different times in the two files (not aligned), they may even be interlaced with other transactions. So, I would like to only be able to see and compare the transactions with a particular type. – omouri Sep 24 '15 at 20:43
  • Beyond Compare doesn't support filtering to only display lines containing a specific string. The best you can do is only displaying differences containing a specific string. – Chris Kennedy Sep 28 '15 at 15:42
  • 1
    Thank you Chris. I guess what I want is not supported. I hope this feature will be added in future versions. If you edit your answer to include that what I'm asking in not possible, I will mark it as the accepted solution. – omouri Sep 28 '15 at 21:10
0

Here's the way I was able to accomplish the desired behavior in BC4.

BC supports running a "pre-processor" application as it opens a file for comparison. So what I did was make a simple executable which takes 3 arguments (argv[]):

  1. The path to the original file
  2. The path to the processed file (which will ultimately be opened for comparison by BC)
  3. The path to a txt file containing line-delimited search substrings (more on this below)

Item number 3 above could contain only one entry (to use the same example as the original question) such as "transactionType: 6". The executable then searches each line of the original file (item 1 above) for the search substrings defined in item 3 above. Every time there is a hit, the whole line is copied (appended) into the output file (item 2 above).

Next, you need to define a File Format in BC (on a Mac you go to Beyond Compare menu and click on File Formats...). Select your file's extension and click on the Conversion tab. Use the screenshot below as example. Note: %s is defined by BC to refer to the path of the original file (item 1) and %t refers to the path of the processed file (item 2).

screenshot

So, when you open File1.txt and File2.txt for comparison, BC will invoke your executable (once for each) and then open the resulting files (item 2). This will effectively show a "filtered" version of both files showing only lines containing the search substring.

Also note that the %t argument will be some sort of temp path generated internally by BC.

Below is a quick-and-dirty implementation of the executable described above:

#include <iostream>
#include <fstream>
#include <list>
#include <string>
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;
}

Hope this helps!

omouri
  • 15
  • 1
  • 6