Organize in lines all blocks that are in columns

Help with writing and running scripts

Organize in lines all blocks that are in columns

Postby cgcamal » Mon Nov 03, 2008 12:14 am

Hi to all,

Please some help from the experts.

I have a text file with system user information in two columns divided in blocks, (many blocks)
beginning with "Account user". Within the first column there are words that are repeated through
the file in other blocks information for other users. In second column is written the info related to every
particular user defined in the system as we can see below of every "Account user" field in first column.

*Some blocks contain less fields or lines than others.

I'd like to tabulate, organize the same information putting the repeated fields in the first column as headers in a new file. Saying that the block that contain the maximun number of fields in the 1rst column has 5 fields, the number of columns (or headers) in the new file would be 5, without count the fixed column that would contain the header "Account user". In total would be 6.


Example:

I have this:

Account user
jsmith
Full Name ---------------------- John Smith
User's comment ------------------With this profile I can change everything
Password last set -----------------10/22/08 2:18 PM
Workstations allowed --------- ----All
Group Memberships --------------Administrators Users
Account user
mkendall
Full Name ---------------------- Mark Kendall
Password last set ----------------11/02/2008 7:19
Group Memberships --------- Operators Users
.
.
.
and continues..

I'd like to obtain an arrangement as follow:
(The blocks with less fields would appear with empty spaces under some columns)


Code: Select all
Account user--Full Name-----User's comment------------Password last set----Workstations allowed--Group Memberships
jsmith--------John Smith----I can change everything------10/22/08 2:18 PM----------All----------Administrators Users
mkendall------Mark Kendall-------------------------------11/02/08 7:19 AM-------------------------Operators Users   


Any suggestion on how can I do this will be appreciated.

Thanks in advance.
cgcamal
Basic User
Basic User
 
Posts: 11
Joined: Sun Oct 05, 2008 6:19 pm

Re: Organize in lines all blocks that are in columns

Postby jorrasdk » Mon Nov 03, 2008 4:36 am

You write your question in the macro forum - but is scripts an option for you ? Tell us your version of UE (macro authors need this information too).

(I have a script that almost does what you want, that I can modify and post to this forum if you use UE13 or above).
User avatar
jorrasdk
Master
Master
 
Posts: 275
Joined: Mon Mar 19, 2007 11:00 pm
Location: Denmark

Re: Organize in lines all blocks that are in columns

Postby cgcamal » Mon Nov 03, 2008 8:21 am

Hi jorrasdk, thanks for answer. Well, yes, a script is a good option. I use the last UE version. Thanks again.
cgcamal
Basic User
Basic User
 
Posts: 11
Joined: Sun Oct 05, 2008 6:19 pm

Re: Organize in lines all blocks that are in columns

Postby jorrasdk » Mon Nov 03, 2008 8:40 am

Ok, here goes. I developed and tested the script against these test data (DOS line endings):

Code: Select all
Account user
jsmith
Full Name                        John Smith
User's comment                   I can change everything
Password last set                  10/22/08 2:18 PM
Workstations allowed               All
Group Memberships               Administrators Users

Account user
mkendall
Full Name                        Mark Kendall
Password last set                 11/02/2008 7:19 PM
Group Memberships           Operators Users


The script looks like this. Some comments are added:

Code: Select all
/* Add trim method to String object */
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };

/* Add rpad method to String object */
String.prototype.rpad=function(n,s) { if(n<0) return; if(typeof s=='undefined') s=' '; var res=this.toString(); while(res.length<n) res=res+s; return res; }

/* Define line break characters for file: DOS: \r\n, Unix: \n */
var CRLF = "\r\n";

// Define working environment for this file.
UltraEdit.perlReOn();

// Define all the find options:
UltraEdit.activeDocument.findReplace.mode=0;
UltraEdit.activeDocument.findReplace.searchDown=true;
UltraEdit.activeDocument.findReplace.searchInColumn=false;
UltraEdit.activeDocument.findReplace.matchCase=false;
UltraEdit.activeDocument.findReplace.matchWord=false;
UltraEdit.activeDocument.findReplace.preserveCase=false;
UltraEdit.activeDocument.findReplace.regExp=true;
UltraEdit.activeDocument.findReplace.replaceAll=false;

// Move cursor in current file to top of the file.
UltraEdit.activeDocument.top();

// Remove trailing blanks
UltraEdit.activeDocument.trimTrailingSpaces();

// global arrays for accounts and lengths for columns
var accounts = new Array();
var accountColumnLen = new Array();

// find all blocks of accounts:
while (UltraEdit.activeDocument.findReplace.find("[^ÿ]*?^Account user")) {
  extract_accountData(UltraEdit.activeDocument.selection);
}
// find last account (as it is not followed by ^Account user
UltraEdit.activeDocument.findReplace.find("[^ÿ]*");
extract_accountData(UltraEdit.activeDocument.selection);

// Move cursor back to top in current file
UltraEdit.activeDocument.top();

// Write resulting tabular output to new file
UltraEdit.newFile();

// Define a short alias:
var outputDoc = UltraEdit.document[getActiveDocumentIndex()];

// Now write the tabular list
write_accounts_tabular_list();

// Extract pairs of key=value. Key without value = account short name
function extract_accountData(accountData) {
  // split the list at CRLF
  var accountDataList = accountData.split(CRLF);

  // return if invalid data
  if (! accountDataList) return;
  if (accountDataList.length < 1) return;

  // New array for account being processed
  var account = new Array();

  for (var i = 0;i<accountDataList.length;i++) {
    /* regexp to extract key and value */
    var re_accountDataList = /^(.*?)(  +)(.*)/;
    var keyname = "";
    var keyvalue = "";
    var spaces = "";
    try {
      [, keyname, spaces, keyvalue ] = re_accountDataList.exec(accountDataList[i]);
    }
    catch (ex) {
      /* no value - put whole line in key */
      keyname = accountDataList[i]; keyvalue = "";
    }
    if (keyname.trim()=="") continue; /* drop empty keys */
    if (keyname=="Account user") continue; /* drop "Account user" line */
    if (keyvalue=="") {keyvalue=keyname;keyname = "Account user";} /* no value = username => swap */

    /* assign key/value combination to account array */
    account[keyname] = keyvalue;

    /* calc length of value and save longest length */
    if(! accountColumnLen[keyname]) accountColumnLen[keyname] = 0;
    if(keyvalue.length > accountColumnLen[keyname]) accountColumnLen[keyname] = keyvalue.length;
  }

  /* push account to "master array" */
  accounts.push(account);
}

// Write tabular list
function write_accounts_tabular_list() {
  var outString = "";
  // write header
  for (var colName in accountColumnLen) {
    /* if header is longer than largest value adjust length */
    if(colName.length > accountColumnLen[colName]) accountColumnLen[colName] = colName.length;
    /* add column name and pad with blanks */
    outString += colName.rpad(Number(accountColumnLen[colName]))+ " ";
  }
  outputDoc.write(outString.trim()+CRLF);

  for(var i=0;i<accounts.length;i++) {
    var account = accounts[i];

    outString = "";
    // Iterate through all columns
    for (var colName in accountColumnLen) {
      var val = account[ colName ];

      // undefined column for this account => use blank
      if(val==undefined) val = "";

      // add column value and pad with blanks.
      outString += val.rpad(Number(accountColumnLen[colName]))+ " ";
    }

    // write data
    if(outString.trim()!="") {
      outputDoc.write(outString.trim()+CRLF);
    }
  }
}

/* Find the tab index of the active document */
function getActiveDocumentIndex() {
  var tabindex = -1; /* start value */

  for (i = 0; i < UltraEdit.document.length; i++)
  {
    if (UltraEdit.activeDocument.path==UltraEdit.document[i].path) {
      tabindex = i;
      break;
    }
  }
  return tabindex;
}


Run the script with the test data as the active file. It then produces the following output:

Code: Select all
Account user Full Name    User's comment          Password last set  Workstations allowed Group Memberships
jsmith       John Smith   I can change everything 10/22/08 2:18 PM   All                  Administrators Users
mkendall     Mark Kendall                         11/02/2008 7:19 PM                      Operators Users
User avatar
jorrasdk
Master
Master
 
Posts: 275
Joined: Mon Mar 19, 2007 11:00 pm
Location: Denmark

Re: Organize in lines all blocks that are in columns

Postby cgcamal » Mon Nov 03, 2008 11:27 pm

Hi jorrasdk,

This code really works! It is how I was thinking about, you got my idea perfectly! :D

Many thanks to take your time to help others with their problems and things like this.

Best regards
cgcamal
Basic User
Basic User
 
Posts: 11
Joined: Sun Oct 05, 2008 6:19 pm


Return to Scripts