Read one file and use it to parse another 1 liner

Help with writing and running scripts

Read one file and use it to parse another 1 liner

Postby sklad2 » Thu Jun 12, 2008 4:16 pm

I have two files. One has the parameters I need to split a line into pieces. The other file is a one line file. I woud like to read from the file that tells me how to split the line on the other file and then under that line in the file put each piece on consecutive lines.
For example for the one line file:

Code: Select all
11111111222222222444444499999999

For the parameter file:

Code: Select all
 val1        position  (4:11)   
 val2        position (12:12)
 val3        position (13:16)

Now first the numbers are not in any pariticular column but they are always in the format (number:number)

So now I would read the first line and figure out that columns 4 - 11 go on the next line. I would like to terminate each new line with a | character

Code: Select all
11111111222222222444444499999999
11112222|

The next line says 12 - 12

Code: Select all
11111111222222222444444499999999
11112222|
2|

and so on reading from the second file , rewriting the first until there are no more (number:number) lines left.

All help is appreciated.

I am using UE 14.00b
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am

Re: Read one file and use it to parse another 1 liner

Postby jorrasdk » Mon Jun 16, 2008 4:18 am

Here is something to get started on. I hope the script comments explain what is being done. If not then ask in this thread.

Code: Select all
// Define working environment for this file.
UltraEdit.perlReOn();
UltraEdit.insertMode();
UltraEdit.columnModeOff();

// Helper function as UE does not recognize start and ending slashes in regexp
RegExp.prototype.toUEregexp = function() { return this.toString().replace(/^\/|\/$/g, ""); }; /* remove starting and ending slashes */

// Where to find the parmfile:
var parmfile = "c:\\temp\\parmfile.txt";

// Now go get parm file and parse it into an array of parameters
var parms = getParms(parmfile);

// "One line file"
var onelinefile = "c:\\temp\\onelinefile.txt";

// Now parse and reformat one line file from parameters
parseOneLineFile(onelinefile);


/* Parse parameter document to get parameters */
function getParms(parmfilePath) {
  var parsedParms = new Array();

  // Open parm file if not open already
  var parmdocIx = getDocumentIndex(parmfilePath);
  var parmdocOpen = true;
  if(parmdocIx==-1) { /* not open */
    UltraEdit.open(parmfilePath);
    parmdocIx = getDocumentIndex(parmfilePath);
    parmdocOpen = false;
  }

  if(parmdocIx==-1) { /* just in case, no parm file found */
    return parsedParms;
  }

  // Define all the replace options to correct execute the follwing 2 replace all commands.
  UltraEdit.document[parmdocIx].findReplace.mode=0;
  UltraEdit.document[parmdocIx].findReplace.searchDown=true;
  UltraEdit.document[parmdocIx].findReplace.searchInColumn=false;
  UltraEdit.document[parmdocIx].findReplace.matchCase=false;
  UltraEdit.document[parmdocIx].findReplace.matchWord=false;
  UltraEdit.document[parmdocIx].findReplace.preserveCase=false;
  UltraEdit.document[parmdocIx].findReplace.regExp=true;

  // Find parameter definitions - "from" = (tagged expression) $1 and "to" = $2 :
  //  val1        position  (4:11)
  var reParms = /\((\d+):(\d+)\)/; /* perl regular expression */

  UltraEdit.document[parmdocIx].top();
  // Loop and find all parameters
  while (UltraEdit.document[parmdocIx].findReplace.find(reParms.toUEregexp())) {
    // retrieve found parameter definition
    var foundParmDefs = UltraEdit.document[parmdocIx].selection;

    // Re-execute regexp on paramter definition to get from and to positions:
    var [,fromPos,toPos] = reParms.exec(foundParmDefs);

    // collect pairs of parameter definitions into array:
    parsedParms.push( [parseInt(fromPos),parseInt(toPos)] );
  }

  if(parmdocOpen==false) { /* not open, then close again on exit */
    UltraEdit.closeFile(UltraEdit.document[parmdocIx].path,2);
  }

  return parsedParms;
}


/* Parse and reformat */
function parseOneLineFile(onelinefilePath) {
  // Open "one line file" if not open already */
  var inputdocIx = getDocumentIndex(onelinefilePath);
  if(inputdocIx==-1) { /* not open */
    UltraEdit.open(onelinefilePath);
    inputdocIx = getDocumentIndex(onelinefilePath);
  }

  if(inputdocIx==-1) {
    return; /* nothing to do */
  }

  if(parms.length==0) {
    return; /* no parms, nothing to do */
  }

  // Get 1st line
  UltraEdit.document[inputdocIx].top();
  UltraEdit.document[inputdocIx].selectLine();
  var oneline = UltraEdit.document[inputdocIx].selection;

  // Make sure last line ends with CR+LF
  UltraEdit.document[inputdocIx].bottom();
  if(UltraEdit.document[inputdocIx].currentColumnNum>0) {
    UltraEdit.document[inputdocIx].insertLine();
  }

  // loop through parameters
  for(var i=0;i<parms.length;i++) {

    if(parms[i][0]<=parms[i][1]) { /* just in case */
      var len = parms[i][1] - parms[i][0] + 1;

      // Now write substring of "one line":
      UltraEdit.document[inputdocIx].write(oneline.substr(parms[i][0],len)+"|");
      // Insert new line
      UltraEdit.document[inputdocIx].insertLine();
    }
  }

}

/* getDocumentIndex(filepath) */
/* If called without parameter = Find the tab index of the active document */
/* If called with parameter "filepath" = Find the tab index of that document. -1 = document not found */
function getDocumentIndex(filepath) {
  var tabindex = -1; /* start value */

  for (i = 0; i < UltraEdit.document.length; i++)
  {
    if(filepath) {
      if (UltraEdit.document[i].path.toLowerCase().indexOf(filepath.toLowerCase())!=-1) {
        tabindex = i;
        break;
      }
    }
    else {
      if (UltraEdit.activeDocument.path==UltraEdit.document[i].path) {
        tabindex = i;
        break;
      }
    }
  }
  return tabindex;
}


Your parameters result in this output when the script is run on the "one line file":

Code: Select all
11111111222222222444444499999999
11112222|
2|
2222|
User avatar
jorrasdk
Master
Master
 
Posts: 275
Joined: Mon Mar 19, 2007 11:00 pm
Location: Denmark

Re: Read one file and use it to parse another 1 liner

Postby sklad2 » Tue Jun 17, 2008 12:35 pm

I really appreciate the help with this!!!! The code is amazing! I was going at it like this before your code.
Code: Select all
1. try to open param file
2. try to open record file
3. read one line in param file , if it had the numbers ,try to parse it and then try to copy col:col to a new line in record file.
4. over and over for 3.


I really like your way. I am trying to understand how the number:number is getting parsed into variables.


Thanks,
Steven
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am

Re: Read one file and use it to parse another 1 liner

Postby sklad2 » Wed Aug 06, 2008 9:13 am

Code: Select all
var [,fromPos,toPos] = reParms.exec(foundParmDefs);


What does this line of code do?
What variable does it refer to?
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am

Re: Read one file and use it to parse another 1 liner

Postby jorrasdk » Thu Aug 07, 2008 1:48 am

It's a combination of two things:

Code: Select all
var [ , fromPos,toPos] = ...


Is a so called destructuring assignment - new in JavaScript 1.7 - see the chapter on Destructuring assignment at Mozilla.org...

The second thing

Code: Select all
... = reParms.exec(foundParmDefs);


The exec method is executing ther regular expression reParms on the variable foundParmDefs. The result is an array. Index [0] is the total match by the regular expression. Additional index values correspond with captures in the regular expression.

In the destructuring assignment statement I was not interested in the total match, only the captured start and to position. That was why I didn't use a variable for the total match. Otherwise it might have looked something like:

Code: Select all
var [totalMatchOfRegExp, fromPos, toPos] = reParms.exec(foundParmDefs)


If you prefer not to use destructuring assignment, just let the result of exec go into an array:
Code: Select all
var myArray = reParms.exec(foundParmDefs);
UltraEdit.messageBox("Total match of regexp = "+myArray[0]);
User avatar
jorrasdk
Master
Master
 
Posts: 275
Joined: Mon Mar 19, 2007 11:00 pm
Location: Denmark

Re: Read one file and use it to parse another 1 liner

Postby sklad2 » Thu Aug 07, 2008 9:50 am

Thanks a million for showing me where this syntax is in the docs. Also how do we know which version of javascript is used by any particular version of UE?

Should UE be totally compliant with the version. I have tried a few Javascript ( 1.7 ) examples and found some the object examples do not work with UE latest and hotfixes.
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am

Re: Read one file and use it to parse another 1 liner

Postby jorrasdk » Thu Aug 07, 2008 9:56 am

Well if we check with the UE help it says:

UE help wrote:The scripting engine supports the core functionality of JavaScript 1.7. Further information on JavaScript may be found on the associated Mozilla site (http://developer.mozilla.org/en/docs/JavaScript).

Please could you tell us which 1.7 functionality(-ies) you have tried, that don't work with UE 14.10 ? Thanks.
User avatar
jorrasdk
Master
Master
 
Posts: 275
Joined: Mon Mar 19, 2007 11:00 pm
Location: Denmark

Re: Read one file and use it to parse another 1 liner

Postby sklad2 » Thu Aug 07, 2008 10:17 am

Great. I was looking in the Help about box. I will submit the examples.
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am

Re: Read one file and use it to parse another 1 liner

Postby sklad2 » Fri Aug 08, 2008 10:50 am

Code: Select all
function fib() {
  var i = 0, j = 1;
  while (true) {
    yield i;
    var t = i;
    i = j;
    j += t;
  }
}

var g = fib();
for (var i = 0; i < 10; i++) {
  UltraEdit.outputWindow.write(g.next() + "<br>\n");
}


I get the following in the output window
Code: Select all
Running script: C:\temp\t1.js
========================================================================================================
An error occurred on line 4:
      yield i;

Script failed.
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am

Re: Read one file and use it to parse another 1 liner

Postby jorrasdk » Fri Aug 08, 2008 11:18 am

I get the same result. Maybe the answer is
http://developer.mozilla.org/en/docs/New_in_JavaScript_1.7#Using_JavaScript_1.7 wrote:In order to use some of the new features of JavaScript 1.7, you need to specify that you wish to use JavaScript 1.7. In HTML or XUL code, use:

<script type="application/javascript;version=1.7"/>

When using the JavaScript shell, you need to set the version you wish to use using the -version 170 switch on the command line or using the version() function:

version(170);

The features that require the use of the new keywords "yield" and "let" require you to specify version 1.7 because existing code might use those keywords as variable or function names. The features that do not introduce new keywords (destructuring assignment and array comprehensions) can be used without specifying the JavaScript version.


If you are going to use yield you might want to send IDM Support an e-mail (see e-mail at the top of the page) asking if they set the version flag to 170 when embedding the javascript interpreter in UE.
User avatar
jorrasdk
Master
Master
 
Posts: 275
Joined: Mon Mar 19, 2007 11:00 pm
Location: Denmark

Re: Read one file and use it to parse another 1 liner

Postby sklad2 » Fri Aug 08, 2008 1:01 pm

I believe you are correct. All examples now work except for the
Code: Select all
yield

Removing
Code: Select all
let
all other examples worked with expected results unless yield was attempted. I also see that some cases will not work because let is not working without the yield keyword.
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am

Re: Read one file and use it to parse another 1 liner

Postby sklad2 » Fri Jun 19, 2009 11:41 am

This script works great except for two minor issues.
1. If the input file has spaces, UE tends to show the line incorrectly. It is like it is indenting the spaces. I have just replaced all spaces with a symbol not regulately found in the records and now the parse looks great. Always been a problem.
2. As of the lastest UE, all of a sudden it is one off for the start of the each field.
ex.
position ( 1:8 )
takes
123456789
and now makes it
123456789
23456789
I changed the script to subtract 1 from the start and I think it is working, but do not know why this started happening.

I have also noticed now that it does not ignore case doing the search. Actually all of my scripts not show two different behaviours.
1. ignore case does not ignore case.
2. the start of an array is not based on 0 , now it is one 1.

I am running the latest and greatest.
User avatar
sklad2
Advanced User
Advanced User
 
Posts: 58
Joined: Thu Mar 08, 2007 12:00 am


Return to Scripts