User to user discussion and support for UltraEdit, UEStudio, UltraCompare, and other IDM applications.

Find, replace, find in files, replace in files, regular expressions
4 posts Page 1 of 1
I have been searching and trying but have not found a solution yet for what I am wanting to do. I want to search on various data points using NOAA's weather output models, an example of the format is below. Specifically, I want to search for something like the immediate below.

Code: Select all
FW CL CL
 8  8  8

I have tried column mode with Find using Shift + Enter to have the second line, but in the text box it shows a carriage return for the entire first line, which returns zero results. Is there a way to do this in UE? TIA

Code: Select all
KCRP   GFS LAMP GUIDANCE  10/10/2016  1400 UTC                                  
 UTC  15 16 17 18 19 20 21 22 23 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
 TMP  72 77 80 83 84 85 86 85 83 79 75 72 70 68 67 65 64 63 63 63 63 63 64 70 76
 DPT  55 53 53 51 51 51 51 52 54 56 56 56 56 55 56 56 56 56 57 57 58 58 60 63 65
 WDR  02 02 04 05 06 07 07 09 10 11 11 11 11 11 09 08 03 01 01 36 36 36 36 35 36
 WSP  08 08 08 07 07 08 09 09 09 07 05 05 04 04 03 03 02 02 02 02 03 04 04 05 07
 WGS  NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG NG
 PPO   0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 PCO   N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N
 P06                              0                 0                 2         
 LP2         0  0  0  0  0  0     0     0     0     0     0     0     0     0   
 LC2         N  N  N  N  N  N     N     N     N     N     N     N     N     N   
 CP2         0  0  0  0  0  0     1     1     0     0     0     0     0     0   
 CC2         N  N  N  N  N  N     N     N     N     N     N     N     N     N   
 POZ   1  0  0  0  0  0  0  0  0  1  1  1  0  0  0  0  0  0  0  0  0  0  0  0  0
 POS   2  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 TYP   R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R  R
 CLD  FW FW FW FW FW FW FW FW FW FW CL CL CL CL CL CL CL CL CL CL CL FW FW FW SC
 CIG   8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8
 CCG   6  6  7  7  8  8  8  7  8  8  8  8  8  6  6  6  6  6  6  7  7  6  6  6  6
 VIS   7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7
 CVS   7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7  7
 OBV   N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N  N
This is really a very special search. A regular expression search is usually used to find a string on line X with another string on line X+1. It would be no problem to use a regular expression search to find a string starting at column Y on line X with another string starting also at column Y on line X+1. But the problem is that the starting column is not fixed if I understood the requirements for this special search. The rectangular block should be found anywhere in file. And last but not least two lines in file could contain the rectangular block to find more than once, like

Code: Select all
 CLD  FW FW FW FW FW FW FW FW FW FW CL CL CL CL CL CL CL CL FW CL CL FW FW FW SC 
 CIG   8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8  8

I'm not sure but I think even a Perl regular expression is not capable for running such a find.

So I wrote an UltraEdit script for finding a string anywhere on a line with another string found exactly below the first found string.

Code: Select all
if (UltraEdit.document.length > 0)  // Is any file opened?
{
   var sFirstToFind = "";
   var sSecondToFind = "";
   var nActiveClipboard = UltraEdit.clipboardIdx;

   // Get data from a previous run of this script stored in user clipboard 9
   // if the active file is the same as on previous execution of the script.
   UltraEdit.selectClipboard(9);
   if (UltraEdit.clipboardContent.length)
   {
      var asFindData = UltraEdit.clipboardContent.split("\r\n");
      if (asFindData[0] == UltraEdit.activeDocument.path)
      {
         sFirstToFind = asFindData[1];
         sSecondToFind = asFindData[2];
      }
      UltraEdit.clearClipboard();
   }
   UltraEdit.selectClipboard(nActiveClipboard);

   // Set caret to right by 1 character on first line if there is still
   // a rectangular block selected from a previous script run to avoid
   // finding the same block once again.
   if ((UltraEdit.activeDocument.isSel()) && UltraEdit.columnMode && sFirstToFind.length)
   {
      UltraEdit.activeDocument.key("RIGHT ARROW");
   }
   UltraEdit.insertMode();
   UltraEdit.columnModeOff();

   // If there are no strings stored in user clipboard 9 from a previous
   // execution of this script on active file ask user for the 2 strings.
   while (!sFirstToFind.length)
   {
      sFirstToFind = UltraEdit.getString("Please enter string to find first:",1);
   }
   while (!sSecondToFind.length)
   {
      sSecondToFind = UltraEdit.getString("Please enter string to find second:",1);
   }

   // Define the parameters for the case-sensitive non regular
   // expression find used to find first string in active file.
   UltraEdit.ueReOn();
   UltraEdit.activeDocument.findReplace.mode=0;
   UltraEdit.activeDocument.findReplace.matchCase=true;
   UltraEdit.activeDocument.findReplace.matchWord=false;
   UltraEdit.activeDocument.findReplace.regExp=false;
   UltraEdit.activeDocument.findReplace.searchDown=true;
   UltraEdit.activeDocument.findReplace.searchInColumn=false;

   var bBlockFound = false;

   // Search for the first string to find from current caret position to
   // end of file in a loop until either the block is found or the first
   // string can't be found anymore in active file.
   while (UltraEdit.activeDocument.findReplace.find(sFirstToFind))
   {
      // Get line and column number of caret which is at end of found string.
      var nActiveLine = UltraEdit.activeDocument.currentLineNum;
      var nActiveColumn = UltraEdit.activeDocument.currentColumnNum;
      var nNextLine = nActiveLine+1;
      var nNextColumn = nActiveColumn-sFirstToFind.length;

      // Set caret to next line at same column as beginning of found string.
      UltraEdit.activeDocument.gotoLine(nNextLine,nNextColumn);
      if ((UltraEdit.activeDocument.currentLineNum == nNextLine) &&
          (UltraEdit.activeDocument.currentColumnNum == nNextColumn))
      {
         // Select everything to end of this line.
         UltraEdit.activeDocument.startSelect();
         UltraEdit.activeDocument.key("END");
         UltraEdit.activeDocument.endSelect();

         if (UltraEdit.activeDocument.isSel())
         {
            // Starts the selected string with second string to find?
            if (UltraEdit.activeDocument.selection.indexOf(sSecondToFind) == 0)
            {
               // Rectangular block to find indeed found in active file. Select the
               // rectangular block in column mode from bottom left to top right.
               UltraEdit.activeDocument.gotoLine(nNextLine,nNextColumn);
               UltraEdit.columnModeOn();
               UltraEdit.activeDocument.gotoLineSelect(nActiveLine,nActiveColumn);

               // Store the strings to find with file name with path in user
               // clipboard 9 for next run of this script on same file.
               UltraEdit.selectClipboard(9);
               UltraEdit.clipboardContent = UltraEdit.activeDocument.path + "\r\n" +
                                            sFirstToFind + "\r\n" + sSecondToFind;
               UltraEdit.selectClipboard(nActiveClipboard);
               bBlockFound = true;
               break;
            }
         }
      }
      // Set caret back to end of first found string and search
      // from this position once again for first string to find.
      UltraEdit.activeDocument.gotoLine(nActiveLine,nActiveColumn);
   }
   if (!bBlockFound) UltraEdit.activeDocument.top();
}

Note: The script works only if the rectangular block to find does not contain horizontal tabs.

Copy the script code into a new ASCII file and save it for example with name FindTwoLinesRectangularBlock.js in directory %APPDATA%\IDMComp\UltraEdit\scripts which first must be created if not already existing. Next add this script to the Scripts List without or with a hotkey or chord assigned to the script for quick execution by key.

On first run of this script on a file the user is prompted for the two strings of the two lines rectangular block to find anywhere in the file.

The script searches in file first for the first entered string and if found checks, if the line below at same starting column has the second entered string. If this is indeed the case, the two found strings are selected in column mode and as a special feature the name of the active file with path and the two entered strings are copied to user clipboard 9. Otherwise the script continues searching for next occurrence of first string in file until the two lines rectangular block is found or the first string could not be find up to end of file.

The script starts searching for next occurrence of first entered string always from current caret position in active file.

As a special feature the two entered strings to find must not be entered again if this script is executed on same file more than once and if on previous run the two lines rectangular block was indeed found in active file from current position of caret to end of file.

Usage example:

  1. The active file contains just the two lines as posted above and caret is at top.
  2. The script is the first time executed on active file. Therefore the user has to enter the two strings "FW CL CL" and " 8  8  8".
  3. The script selects the first found block from line 2 column 34 to line 1 column 42.
  4. The script is executed once again. The user does not need to enter the two strings again.
  5. The script selects the second found block from line 2 column 61 to line 1 column 69.
  6. The script is executed once more. Again the user does not need to enter the two strings.
  7. The script fails to find the two lines rectangular block once more. The caret is set back to top of file.
On next run of the script on this file the two strings of the block to find must be entered again as previous run was not successful to find the rectangular block.
Best regards from Austria
Hi - Thanks for the response! Yes, you are correct about the requirements.

I followed your directions but am getting a Cancel operation dialog error at runtime. I should add that I am using a Mac so that path is not present for me. I did add it from Tools>Scripting though. Does UE have a log file that can be looked at?
A Cancel dialog is always displayed on running a script to be able to break it except Show cancel dialog is not checked at Preferences/Configuration - Scripting (if UE for Mac has this setting which I don't know).

Errors detected by embedded JavaScript interpreter on running an UltraEdit script are written to output window except Show status information in output window is not checked at Preferences/Configuration - Scripting (if UE for Mac has this setting which I don't know).

So it would be good to have the output window opened and visible on running the script to see possible errors output by JavaScript interpreter.

I don't have a Mac or UltraEdit for Mac and therefore can't test the script with UEM.

You may change "\r\n" in script to "\n" as on Mac OS X usually just line-feed is just as line terminator like on UNIX. But that should not really matter for this script.
Best regards from Austria
4 posts Page 1 of 1