Replicate file X times with content modification with an incrementing number

Replicate file X times with content modification with an incrementing number

5
NewbieNewbie
5

    Jan 25, 2021#1

    Hi all,

    Would someone be able to help me to achieve these goals. The goals are to replicate files and modify the content, so I can use these files for testing a system.
    1. Say I have a folder with a file name A1.
    2. I would like a prompt and based on the integer I enter, I would to copy the file and replicated it X amount of time and name that file by incrementing the file like A2, A3.
    3. Inside the file, if I have 5 lines, I would like to find the a word on the same line and increment it as +1. Say on line 5, I have D00001, I would to copy every line and then modify it to D00002, and continue until the integer enter is met.
    Thanks.

    6,686585
    Grand MasterGrand Master
    6,686585

      Jan 25, 2021#2

      Here is an UltraEdit script for this task on which file path and file name at top must be defined by you before it can be run.

      Code: Select all

      var sFilePath = "C:\\Temp\\";
      var sFileName = "A1.txt";
      
      var nFileCount = 0;
      var sSourceFileContent = "";
      var sFullFileName = (sFilePath+sFileName).toLowerCase();
      
      // Define environment for this script.
      UltraEdit.insertMode();
      if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
      else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
      
      // Look in list of opened files for the file with path and name as defined at top.
      if (UltraEdit.document.length > 0)
      {
         for (var nDocIndex = 0; nDocIndex < UltraEdit.document.length; nDocIndex++)
         {
            // The full file name comparison is done with all characters converted
            // to lower case in case of the script author entered the file path or
            // file name at top not exactly has the file name and path is in real.
            if (UltraEdit.document[nDocIndex].path.toLowerCase() == sFullFileName)
            {
               // Select all in current file being the source file, assign the text
               // as string to a string variable, move caret to top to discard the
               // selection and prompt the script user for the number of files to
               // create, except a non-zero value is defined at top of the script.
               UltraEdit.document[nDocIndex].selectAll();
               sSourceFileContent = UltraEdit.document[nDocIndex].selection;
               UltraEdit.document[nDocIndex].top();
               if (!nFileCount) nFileCount= UltraEdit.getValue("How many files should be created?",1);
               break;
            }
         }
      }
      
      // Is the source file content not loaded from already opened source file?
      if (!sSourceFileContent.length)
      {
         // Try to open the file and on success get the source file content and
         // prompt the script user for the number of files to create, except a
         // non-zero value is defined at top of the script. Then close the just
         // opened source file as no longer needed for the remaining task.
         UltraEdit.open(sFilePath+sFileName);
         if (UltraEdit.document.length > 0)
         {
            if (UltraEdit.activeDocument.path.toLowerCase() == sFullFileName)
            {
               if (!nFileCount) nFileCount= UltraEdit.getValue("How many files should be created?",1);
               UltraEdit.activeDocument.selectAll();
               sSourceFileContent = UltraEdit.activeDocument.selection;
               UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
            }
         }
      }
      
      // Is source file content loaded and number of files to create greater one?
      if (sSourceFileContent.length && (nFileCount > 1))
      {
         // Get the existing number from the word starting with D.
         var sNumber = sSourceFileContent.replace(/^[\s\S]*?\bD(\d+\b)[\s\S]*$/,"$1");
         // Was a word starting with D and one or more digits found at all?
         if (sNumber.length < sSourceFileContent.length)
         {
            // Replace each digit of the number by a zero.
            var sAllZeros = sNumber.replace(/\d/g,"0");
            // Replicate the source file as often as requested by script user.
            for (nFileNumber = 2; nFileNumber <= nFileCount; nFileNumber++)
            {
               sNumber = nFileNumber.toString(10);
               // Insert leading zeros if that is needed at all.
               if (sNumber.length < sAllZeros.length) sNumber = sAllZeros.substr(sNumber.length) + sNumber;
               // Create a new file and write the source file content with the
               // number after letter D replaced by current number into the file.
               UltraEdit.newFile();
               UltraEdit.activeDocument.write(sSourceFileContent.replace(/\bD\d+\b/,"D"+sNumber));
               // Save the new file into same directory as the source file with the
               // number in file name replaced by current file number and close the file.
               sNumber = nFileNumber.toString(10);
               UltraEdit.saveAs(sFilePath+sFileName.replace(/\d+/,sNumber));
               UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
            }
         }
      }
      
      Best regards from an UC/UE/UES for Windows user from Austria

      5
      NewbieNewbie
      5

        Jan 26, 2021#3

        Thank Mofi,  It worked, then it stop working. I even copy and replace the code. I don't know why it stop creating files. 

        Also, I have a few questions:

        In the file, when I have this line:

        Code: Select all

        ORC||A0011|||||^^^^^R^EVER|||||||||||<cr>

        It will break the line in the duplicated file as:

        Code: Select all

        ORC||A0011|||||^^^^
        ^R^EVER|||||||||||<cr>
        My last question is when the files are generated, how do I use a script or find in file the amount file created and then replace the field in ORC with the name of the file? So If the file was A0012, I want to open the file and rename that file ORC segment with the file name.

        The goal is to generate test files. I can replicate files then replace the content of that file. So each file is unique.

        6,686585
        Grand MasterGrand Master
        6,686585

          Jan 26, 2021#4

          You should have posted the source file content already in initial post. Then I would have used a different method to write the modified content into each file by using a user clipboard and scripting command paste. The caret character ^ has a special meaning for UltraEdit on using scripting command write which is usually no problem as text files usually do not contain this character at all.

          The updated code below searches now also for a word starting with A instead of D as it looks like A0001 is the string with the number to increment in file content for each file and not D00001 as written in your first post.

          The updated script outputs also information to output window and automatically opens the output window. If the script execution terminates without opening the output window, please open the output window manually and look on the lines there as this means an error occurred during script execution which is written to the output window.

          Code: Select all

          var sFilePath = "C:\\Temp\\";
          var sFileName = "A1.txt";
          
          var nFileCount = 0;
          var sSourceFileContent = "";
          var sFullFileName = (sFilePath+sFileName).toLowerCase();
          
          // Define environment for this script.
          UltraEdit.insertMode();
          if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
          else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
          UltraEdit.selectClipboard(9);
          UltraEdit.clearClipboard();
          
          // Look in list of opened files for the file with path and name as defined at top.
          if (UltraEdit.document.length > 0)
          {
             for (var nDocIndex = 0; nDocIndex < UltraEdit.document.length; nDocIndex++)
             {
                // The full file name comparison is done with all characters converted
                // to lower case in case of the script author entered the file path or
                // file name at top not exactly has the file name and path is in real.
                if (UltraEdit.document[nDocIndex].path.toLowerCase() == sFullFileName)
                {
                   // Select all in current file being the source file, assign the text
                   // as string to a string variable, move caret to top to discard the
                   // selection and prompt the script user for the number of files to
                   // create, except a non-zero value is defined at top of the script.
                   UltraEdit.document[nDocIndex].selectAll();
                   sSourceFileContent = UltraEdit.document[nDocIndex].selection;
                   UltraEdit.document[nDocIndex].top();
                   if (!nFileCount) nFileCount= UltraEdit.getValue("How many files should be created?",1);
                   break;
                }
             }
          }
          
          // Is the source file content not loaded from already opened source file?
          if (!sSourceFileContent.length)
          {
             // Try to open the file and on success get the source file content and
             // prompt the script user for the number of files to create, except a
             // non-zero value is defined at top of the script. Then close the just
             // opened source file as no longer needed for the remaining task.
             UltraEdit.open(sFilePath+sFileName);
             if (UltraEdit.document.length > 0)
             {
                if (UltraEdit.activeDocument.path.toLowerCase() == sFullFileName)
                {
                   if (!nFileCount) nFileCount= UltraEdit.getValue("How many files should be created?",1);
                   UltraEdit.activeDocument.selectAll();
                   sSourceFileContent = UltraEdit.activeDocument.selection;
                   UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
                }
             }
          }
          
          // Is source file content loaded and number of files to create greater one?
          if (sSourceFileContent.length && (nFileCount > 1))
          {
             // Get the existing number from the word starting with A.
             var sNumber = sSourceFileContent.replace(/^[\s\S]*?\bA(\d+\b)[\s\S]*$/,"$1");
             // Was a word starting with D and one or more digits found at all?
             if (sNumber.length < sSourceFileContent.length)
             {
                // Replace each digit of the number by a zero.
                var sAllZeros = sNumber.replace(/\d/g,"0");
                // Replicate the source file as often as requested by script user.
                for (nFileNumber = 2; nFileNumber <= nFileCount; nFileNumber++)
                {
                   sNumber = nFileNumber.toString(10);
                   // Insert leading zeros if that is needed at all.
                   if (sNumber.length < sAllZeros.length) sNumber = sAllZeros.substr(sNumber.length) + sNumber;
                   // Create a new file and write the source file content with the
                   // number after letter D replaced by current number into the file.
                   UltraEdit.newFile();
                   UltraEdit.clipboardContent = sSourceFileContent.replace(/\bA\d+\b/,"A"+sNumber);
                   UltraEdit.activeDocument.paste();
                   // Save the new file into same directory as the source file with the
                   // number in file name replaced by current file number and close the file.
                   sNumber = nFileNumber.toString(10);
                   UltraEdit.saveAs(sFilePath+sFileName.replace(/\d+/,sNumber));
                   UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
                }
                nFileCount--;
                UltraEdit.outputWindow.write("SUCCESS: Created " + nFileCount + " file" + ((nFileCount==1) ? "." : "s."));
                UltraEdit.outputWindow.showWindow(true);
             }
             else
             {
                UltraEdit.outputWindow.write("ERROR: Failed to find number to increment.");
                UltraEdit.outputWindow.showWindow(true);
             }
             
          }
          else
          {
             UltraEdit.outputWindow.write((!sSourceFileContent.length) ?
                 ("ERROR: Failed to load source text from file: " + sFilePath + sFileName) :
                  "ERROR: Number of files to create is: " + nFileCount);
             UltraEdit.outputWindow.showWindow(true);
          }
          
          UltraEdit.clearClipboard();
          UltraEdit.selectClipboard(0);
          
          Best regards from an UC/UE/UES for Windows user from Austria

          5
          NewbieNewbie
          5

            Jan 26, 2021#5

            Hi Mofi,

            Thank you and this new version works well, and logging the error help me as well. I still not an expert to do this, but can edit a bit and read regular expression. Yes, I should have given the original message to start with but here is the full message.

            Code: Select all

            MSH|^~\&|||||20200127135400637||||P|2.x|||||||<cr>
            PID|1|A0000001|A0000001||10002^ABC||20020919|M||||||||||<cr>
            PV1|1||A1||||TEST|||||||||||<cr>
            ORC||A00002|||||^^^^^R^EVER|||||||||||<cr>
            OBR|1|A00001||Test|R||202001271353||||||||Type||||||||||||^^^20140127135300^^R|<cr>
            It is a HL7 message that I use to generate files that another program will use file I/O to read and generate fake orders for testing. The script is doing as it expected, and generate the files creating the file in sequential order. I guess my final question is that, can the script be made where will do the same file creation but replaced all string with A00001 and then with the incremented number? 

            Or could it be made where it will start with the segment PID and increment the number, or I can copy the same sub routine and add ORC, OBR, etc, so in the future, I can add more segments where it will look for that string and then just increment before it copy it into the new file?

            Currently, it seems to changed the ORC segment and doesn't do all matches. If I could make it scalable where I can just add new segments in the future, it would make my life easier generated fake messages for testing. 

            6,686585
            Grand MasterGrand Master
            6,686585

              Jan 27, 2021#6

              Okay, the additional information about the task makes it clear for me that the entire method used to create the files according to first and second task description is not suitable for the task. The script needs to be completely rewritten. I know now the complete file contents which are just a few bytes. It is much more efficient to defined the template text directly in the script instead of loading them from a file using at least two string arrays: one for the fixed strings and another one for the variable strings which define the number of digits. What I would need for not wasting my time a third time is what the files should contain after creation by the script. Please post for the already posted template data also the file contents of the files A1.txt, A2txt and A3.txt. That would make it 100% clear for me which numbers in template text need to be modified using which algorithm on creating the files. You will see that the completely rewritten script will be much easier to adapt on changing the template text defined in the script itself instead of a file.
              Best regards from an UC/UE/UES for Windows user from Austria

              5
              NewbieNewbie
              5

                Jan 28, 2021#7

                Hi Mofi,

                Thanks. As you can see, the goal is to general the files and the ability to change the content like by incrementing the matching string. For example, the segment ORC| contain the an identifier, but for testing purpose, I want to make it easy by starting with an alphabetic character then follow by 1 and incrementing the ID generated. I want be able to use the same routine and add PID|, OBR| and change the matching string in the same format. The goal is to be able to generate unique identification so the system can process them as individual orders.

                If the script can be scalable, I can in the future just add maybe a new segment call NTE| search that string format and then it will change it as well.  I appreciate your guidance and help.

                A1:

                Code: Select all

                MSH|^~\&|||||20200127135400637||||P|2.x|||||||<cr>
                PID|1|A0000001|AA0000001||10002^ABC||20020919|M||||||||||<cr>
                PV1|1||A1||||TEST|||||||||||<cr>
                ORC||A00001|||||^^^^^R^EVER|||||||||||<cr>
                OBR|1|A00001||Test|R||202001271353||||||||Type||||||||||||^^^20140127135300^^R|<cr>
                
                A2:

                Code: Select all

                MSH|^~\&|||||20200127135400637||||P|2.x|||||||<cr>
                PID|1|A0000001|AA0000001||10002^ABC||20020919|M||||||||||<cr>
                PV1|1||A1||||TEST|||||||||||<cr>
                ORC||A00002|||||^^^^^R^EVER|||||||||||<cr>
                OBR|1|A00001||Test|R||202001271353||||||||Type||||||||||||^^^20140127135300^^R|<cr>
                
                A3:

                Code: Select all

                MSH|^~\&|||||20200127135400637||||P|2.x|||||||<cr>
                PID|1|A0000001|AA0000001||10002^ABC||20020919|M||||||||||<cr>
                PV1|1||A1||||TEST|||||||||||<cr>
                ORC||A00003|||||^^^^^R^EVER|||||||||||<cr>
                OBR|1|A00001||Test|R||202001271353||||||||Type||||||||||||^^^20140127135300^^R|<cr>
                

                6,686585
                Grand MasterGrand Master
                6,686585

                  Jan 28, 2021#8

                  The script below creates the files with PID, ORC and OBR numbers incremented although your examples have only ORC incremented in each file. It should not be too difficult to adapt the script to your needs now by yourself.

                  Code: Select all

                  var sFilePath = "C:\\Temp\\";  // Path of existing directory in which the files are created.
                  var sFileNameStart = "A";      // Text at start of the file names of the created files.
                  var sFileNameExt = ".txt";     // File extension of the created files.
                  var bFileNameZeros = true;     // No/yes for inserting leading zeros in file names to
                                                 // save all files with identical length of file name.
                  
                  // Array of fixed strings. The incremented numbers are inserted between
                  // these strings. An empty string with "" can be used if a incremented
                  // number should be at top of the file or at end of the file or if
                  // there should be two incremented numbers with nothing between them.
                  // The number of string in this array must be always exactly one more
                  // than the number of strings in the next array.
                  // Note 1: A literal backslash must be escaped with one more backslash.
                  // Note 2: \r\n represents carriage return and line-feed (DOS/Windows line ending).
                  var asFixed = [
                     "MSH|^~\\&|||||20200127135400637||||P|2.x|||||||<cr>\r\n\PID|1|A",
                     // PID number inserted here.
                     "|AA0000001||10002^ABC||20020919|M||||||||||<cr>\r\nPV1|1||A1||||TEST|||||||||||<cr>\r\nORC||A",
                     // ORC number inserted here.
                     "|||||^^^^^R^EVER|||||||||||<cr>\r\nOBR|1|A",
                     // OBR number inserted here.
                     "||Test|R||202001271353||||||||Type||||||||||||^^^20140127135300^^R|<cr>\r\n"
                  ];
                  
                  // Array of incremented number strings. The number of zeros defines
                  // the number of digits of each incremented number. Use just "0" if
                  // the number of digits does not matter.
                  var asNumbers = [
                     "0000000",  // PID number
                     "00000",    // ORC number
                     "00000"     // OBR number
                  ];
                  
                  if ((asFixed.length-1) == asNumbers.length)
                  {
                     var nFileCount = 0;
                     while (nFileCount < 1) nFileCount= UltraEdit.getValue("How many files should be created?",1);
                  
                     var sFileNameZeros = "";
                     if (bFileNameZeros)  // Convert the number of files to a string and replace each
                     {                    // digit in that string by 0 for leading zeros in file name.
                        sFileNameZeros = nFileCount.toString(10);
                        sFileNameZeros = sFileNameZeros.replace(/./g,"0");
                     }
                  
                     // Define environment for this script.
                     UltraEdit.insertMode();
                     if (typeof(UltraEdit.columnModeOff) == "function") UltraEdit.columnModeOff();
                     else if (typeof(UltraEdit.activeDocument.columnModeOff) == "function") UltraEdit.activeDocument.columnModeOff();
                     UltraEdit.selectClipboard(9);
                     UltraEdit.clearClipboard();
                  
                     var sFileContent;
                     var sFileNumber;
                     var sFullFileName;
                     var nNumberIndex;
                  
                     for (var nFileNumber = 1; nFileNumber <= nFileCount; nFileNumber++)
                     {
                        sFileNumber = nFileNumber.toString(10);
                        sFileContent = asFixed[0];
                  
                        nNumberIndex = 0;
                        while (nNumberIndex < asNumbers.length)
                        {
                           // Append the current file number with or without additional leading zeros.
                           sFileContent += (sFileNumber.length < asNumbers[nNumberIndex].length) ? (asNumbers[nNumberIndex].substr(sFileNumber.length) + sFileNumber) : sFileNumber;
                           nNumberIndex++;
                           sFileContent += asFixed[nNumberIndex];
                        }
                  
                        // Create a new file, make sure DOS/Windows line endings is defined
                        // for the new file, paste the file content created above into the
                        // file, build the full qualified file name, save the new file with
                        // the file name and close the file without an additional save.
                        UltraEdit.newFile();
                        UltraEdit.activeDocument.unixMacToDos();
                        UltraEdit.clipboardContent = sFileContent;
                        UltraEdit.activeDocument.paste();
                        sFullFileName = sFilePath + sFileNameStart;
                        sFullFileName += (sFileNumber.length < sFileNameZeros.length) ? (sFileNameZeros.substr(sFileNumber.length) + sFileNumber) : sFileNumber;
                        sFullFileName += sFileNameExt;
                        UltraEdit.saveAs(sFullFileName);
                        UltraEdit.closeFile(UltraEdit.activeDocument.path,2);
                     }
                  
                     UltraEdit.outputWindow.write("SUCCESS: Created " + nFileCount + " file" + ((nFileCount==1) ? "." : "s."));
                     UltraEdit.outputWindow.showWindow(true);
                     UltraEdit.clearClipboard();
                     UltraEdit.selectClipboard(0);
                  }
                  else UltraEdit.messageBox("Error in script!\nNumber of fixed strings is: "+asFixed.length+
                                            "\nNumber of number strings is: "+asNumbers.length);
                  
                  Best regards from an UC/UE/UES for Windows user from Austria

                  5
                  NewbieNewbie
                  5

                    Jan 30, 2021#9

                    Hi Mofi,

                    Thank you for your time and I appreciate it well. It works great, I'll play around with it and tweak it. I appreciated all your help. You're awesome!