UniqueOcc: a FINDSTR formatter

The UniqueOcc (from unique occurrence) is a command-line tool that parses the output of the FINDSTR tool that we normally use to search XPO files contents (specially files in the Dynamics AX version control repositories, such as Source Depot).

The FINDSTR is really usefull for searching an entire directory and its subdirectories for XPO files containing specific words. For example, if you want to know which classes, forms, tables, etc. use the Legal Text feature, you would get a fair estimated by running:

C:\Depot\AX\Source\Application\GLS>findstr /i /s "legaltxt" *.xpo

This command will search all XPO files (*.xpo) for the “legaltxt” string, starting in the GLS directory, including all subdirectories (/s) and using an insensitive case (/i) comparison.

The classical FINDSTR output would be:

Classes\NFFiscalDoc_BR.xpo:        #    FiscalDocJourLegalTxt_BR          ...
Classes\NFFiscalDoc_BR.xpo:        #    FiscalDocTransLegalTxt_BR         ...
Classes\NFFiscalDoc_BR.xpo:      SOURCE #postLegalTxt
Classes\NFFiscalDoc_BR.xpo:        #protected void postLegalTxt()
Classes\NFFiscalDoc_BR.xpo:        #    this.postFiscalDocJourLegalTxt();
Classes\NFFiscalDoc_BR.xpo:        #            this.postFiscalDocTransLeg...
Classes\NFFiscalDoc_BR.xpo:        #        nfFiscalDoc.postLegalTxt();
Classes\NFFiscalDoc_DeliverySlip_BR.xpo:      SOURCE #getCFOPLegalTxt
Classes\NFFiscalDoc_DeliverySlip_BR.xpo:        #protected LegalTxt_BR ins...
Classes\NFFiscalDoc_DeliverySlip_BR.xpo:        #    LegalTxt_BR     local...
Classes\NFFiscalDoc_DeliverySlip_BR.xpo:        #        localLegalTxts = ...
Classes\NFFiscalDoc_DeliverySlip_BR.xpo:        #        localLegalTxts = ...
Classes\NFFiscalDoc_DeliverySlip_BR.xpo:        #        localLegalTxts = ...
Classes\NFFiscalDoc_DeliverySlip_BR.xpo:        #    return localLegalTxts
(...many, many, many more lines...)

To avoid scrolling and filter it a lot to find which artefacts do have the string you are looking for, you can use the ‘/m’ switch, which will output:

Data Dictionary\Base Enums\LegalTxtSection_BR.xpo
Data Dictionary\Extended Data Types\LegalTxtDescription_BR.xpo
Data Dictionary\Extended Data Types\LegalTxtId_BR.xpo

For those curious C++ programmers, the ‘/m’  switch is equivalent to:

#include "stdafx.h"
#include <iostream>
#include <set>
#include <string>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
	string		line;
	set<string>	lineSet;

	while (!cin.eof())
		getline(cin, line);
		line = line.substr(0, line.find(':'));
		if (lineSet.insert(line).second)
			cout << line << endl;

	return 0;

It parses each line, extracting only the path and the name of the XPO file, then printing only the new occurrences.

But then we lack information, for example, if the word being searched appears on some files more often than on others. The UniqueOcc tool adds some extra (and optional) features to this code such as:

  • Line counting: shows how many lines in the XPO have the search string.
  • Colors: different colors for the XPO path, XPO name and line counting.
  • Path grouping: groups the paths (which indicates classes, forms, tables, etc.)

By running the following command in the desired directory:

findstr /i /s "legaltxt" *.xpo | UniqueOcc

the FINDSTR is parsed and we get an easier output to be analysed (ok, I admit I’m bad at choosing colors):

You can also use it with stored files containing the FINDSTR output:

findstr /i /s "legaltxt" *.xpo > legaltxt.txt
type legaltxt.txt | UniqueOcc

The extra features can be turned off by the following parameters:

findstr /i /s "legaltxt" *.xpo | UniqueOcc -nocount -nocolor -nogroup

which disables the line counting (-nocount), the words coloring (-nocolor) and the path grouping (-nogroup).

By accepting the blog’s disclaimer, you can download the following files:

This entry was posted in C++, Dynamics AX, English. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>