Sorting numbers within a line on all lines of a file

Sorting numbers within a line on all lines of a file

24
Basic UserBasic User
24

    Feb 02, 2012#1

    Hi,

    I'm having a hard time trying to perform simple sorting on UltraEdit.

    The file is 100% ASCII, but I'm trying to sort some numbers on it, here is a sample:

    Code: Select all

    01 02 03 04 06 17 19 28 33 43 47 53 54 69 71 78 84 86 89 97 27 28 42 44 53 54 57 59 61 63 65 74 78 79 80 83 86 87 95 96
    01 02 03 04 09 10 15 23 25 28 34 41 48 54 72 76 86 87 93 00 26 27 39 42 45 50 54 55 63 67 73 78 79 87 90 91 95 96 99 00
    01 02 03 04 10 21 23 29 33 43 49 50 51 60 66 70 74 77 78 80 24 26 38 42 48 49 51 52 54 60 62 63 66 74 82 85 86 87 92 99
    01 02 03 04 10 23 29 38 50 51 54 59 60 61 71 72 74 83 90 91 23 30 31 34 35 43 45 46 48 49 53 55 68 75 83 85 88 95 96 99
    01 02 03 05 12 16 19 20 27 30 33 39 49 51 59 68 74 80 82 83 23 24 31 39 40 41 46 50 52 56 57 59 64 77 83 84 85 90 91 98
    01 02 03 06 07 09 13 23 26 29 34 43 55 60 66 68 81 86 87 97 22 37 43 44 48 54 55 61 67 68 72 79 84 87 91 93 97 98 99 00
    01 02 03 06 08 10 12 13 27 36 39 43 45 49 65 72 73 74 87 90 22 31 40 42 44 48 58 61 62 65 68 71 74 77 78 81 83 84 95 96
    01 02 03 06 12 21 31 35 46 47 48 50 51 52 59 64 69 71 89 90 22 23 30 31 34 36 48 50 54 56 57 59 61 64 67 80 95 97 98 00
    01 02 03 08 14 23 29 33 34 38 43 44 49 52 55 62 65 71 74 94 21 29 31 37 40 44 45 50 55 61 62 79 80 81 83 85 86 88 95 97
    01 02 03 10 24 27 32 52 53 62 70 72 78 79 80 87 91 94 97 98 21 26 29 34 37 50 53 56 58 60 67 68 72 77 79 81 83 92 99 00
    As you can see the first line needs to become as:

    Code: Select all

    01 02 03 04 06 17 19 27 28 33 42 43 44 47 53 54 57 59 61 63 65 69 71 74 78 79 80 83 84 86 87 89 95 96 97
    However, there are some replicated numbers and they need to be deleted as well. On the above example they were: 28 53 54 78 86

    How can I do that?

    Thanks,
    Fernando

    6,603548
    Grand MasterGrand Master
    6,603548

      Feb 03, 2012#2

      That task requires an UltraEdit script and here it is.

      Code: Select all

      if (UltraEdit.document.length > 0)
      {
         // Define the environment for the script.
         UltraEdit.insertMode();
         UltraEdit.columnModeOff();
         UltraEdit.activeDocument.hexOff();
         // Select all and load the file contents into an array of lines.
         UltraEdit.activeDocument.selectAll();
         if (UltraEdit.activeDocument.isSel())
         {
            var asLines = UltraEdit.activeDocument.selection.split("\r\n");
            // Sort the space separated numbers within every line.
            for (var nLineNum = 0; nLineNum < asLines.length; nLineNum++)
            {
               if (!asLines[nLineNum].length) continue;  // Ignore empty lines.
               // Split the line up into an array of number strings.
               var asNumbers = asLines[nLineNum].split(" ");
               // Run a simple string sort based on ASCII table.
               asNumbers.sort();
               // Remove duplicate numbers.
               var nNumberIndex = 0;
               while (nNumberIndex < (asNumbers.length -1))
               {
                  // Is current number string equal next number string in sorted array?
                  if (asNumbers[nNumberIndex] == asNumbers[nNumberIndex+1])
                  {
                     asNumbers.splice(nNumberIndex+1,1);  // Yes, remove next string.
                  }
                  else
                  {
                     nNumberIndex++;  // No, continue with next number string.
                  }
               }
               // Rebuild the line with the sorted numbers with duplicates removed.
               asLines[nLineNum] = asNumbers.join(" ");
            }
            // Replace the still existing selection by resorted lines.
            UltraEdit.activeDocument.write(asLines.join("\r\n"));
         }
      }

      24
      Basic UserBasic User
      24

        Feb 03, 2012#3

        It works! You da man! Thanks a lot!

          Feb 11, 2012#4

          Hi Mofi,

          Really sorry to bother you again.

          Right now I need another little script capable to count the total of odd and even per line, putting the result at the end as "O:n1 E:n2" (in that same line).

          Example:

          Code: Select all

          01 02 03 06 07 09 13 23 26 29 34 43 55 60 66 68 81 86 87 97 22 37 43 44 48 54 55 61 67 68 72 79 84 87 91 93 97 98 99 00   (O:23  E:17)
          Of course the example above have the numbers in out of order, but I'll do them in order.  Keep in mind 00 should remain as 00 at the end of line if present, but since is just counting I don't believe it would change anything.

          Thanks!

          6,603548
          Grand MasterGrand Master
          6,603548

            Feb 14, 2012#5

            That was an easy job. Here is the script.

            Code: Select all

            if (UltraEdit.document.length > 0)
            {
               // Define the environment for the script.
               UltraEdit.insertMode();
               UltraEdit.columnModeOff();
               UltraEdit.activeDocument.hexOff();
               // Select all and load the file contents into an array of lines.
               UltraEdit.activeDocument.selectAll();
               if (UltraEdit.activeDocument.isSel())
               {
                  var asLines = UltraEdit.activeDocument.selection.split("\r\n");
                  // Count the even and odd numbers in the lines with space separated numbers.
                  for (var nLineNum = 0; nLineNum < asLines.length; nLineNum++)
                  {
                     if (!asLines[nLineNum].length) continue;  // Ignore empty lines.
                     // Split the line up into an array of number strings.
                     var asNumbers = asLines[nLineNum].split(" ");
                     var nOddCnt = 0;
                     var nEvenCnt = 0;
                     // Count the even and odd numbers.
                     for (var nNumberIndex = 0; nNumberIndex < asNumbers.length; nNumberIndex++)
                     {
                        // The decimal numbers as strings must be converted to integers.
                        var nValue = parseInt(asNumbers[nNumberIndex],10);
                        if ((nValue % 2) == 0) nEvenCnt++;
                        else nOddCnt++;
                     }
                     // Append the result as string to every not empty line. The two integer
                     // values are automatically converted here to strings by JavaScript core.
                     asLines[nLineNum]+= " (O:" + nOddCnt + " E:" + nEvenCnt + ")";
                  }
                  // Replace the selection by the lines with the even and odd counts.
                  UltraEdit.activeDocument.write(asLines.join("\r\n"));
                  UltraEdit.activeDocument.top();
               }
            }

            24
            Basic UserBasic User
            24

              Feb 19, 2012#6

              Thanks it works!

                Mar 29, 2013#7

                Hi,

                I need a new filter, where it perform sort first and then removes duplicated numbers, line by line. Number range is from 01 to 00 (where 00 is like 100).

                Example:

                Code: Select all

                03 07 11 13 14 16 15 19 23 25 26 28 27 25 31 35 37 38 35 40 39 43 47 49 50 52 51 55 59 61 62 64 63 67 71 73 74 76 75 79 83 85 86 88 87 91 95 97
                Result in:

                Code: Select all

                03 07 11 13 14 15 16 19 23 25 26 27 28 31 35 37 38 39 40 43 47 49 50 51 52 55 59 61 62 63 64 67 71 73 74 75 76 79 83 85 86 87 88 91 95 97
                Looks like this would do the trick:

                Code: Select all

                if (UltraEdit.document.length > 0)
                {
                   // Define the environment for the script.
                   UltraEdit.insertMode();
                   UltraEdit.columnModeOff();
                   UltraEdit.activeDocument.hexOff();
                   // Select all and load the file contents into an array of lines.
                   UltraEdit.activeDocument.selectAll();
                   if (UltraEdit.activeDocument.isSel())
                   {
                      var asLines = UltraEdit.activeDocument.selection.split("\r\n");
                      // Sort the space separated numbers within every line.
                      for (var nLineNum = 0; nLineNum < asLines.length; nLineNum++)
                      {
                         if (!asLines[nLineNum].length) continue;  // Ignore empty lines.
                         // Split the line up into an array of number strings.
                         var asNumbers = asLines[nLineNum].split(" ");
                         // Run a simple string sort based on ASCII table.
                         asNumbers.sort();
                         // Remove duplicate numbers.
                         var nNumberIndex = 0;
                         while (nNumberIndex < (asNumbers.length -1))
                         {
                            // Is current number string equal next number string in sorted array?
                            if (asNumbers[nNumberIndex] == asNumbers[nNumberIndex+1])
                            {
                               asNumbers.splice(nNumberIndex+1,1);  // Yes, remove next string.
                            }
                            else
                            {
                               nNumberIndex++;  // No, continue with next number string.
                            }
                         }
                         // Move 00 as first string to end of the array with the numbers.
                         if (asNumbers[0] == "00")
                         {
                            asNumbers.shift();     // Remove 00 from beginning of array.
                            asNumbers.push("00");  // Append 00 at the end of the array.
                         }
                         // Rebuild the line with the sorted numbers with duplicates removed.
                         asLines[nLineNum] = asNumbers.join(" ");
                      }
                      // Remove last string from array if it is an empty string
                      // because the file ends with a line termination.
                      if(asLines[asLines.length-1] == "") asLines.pop();
                      asLines.sort();   // Sort the lines alphabetically.
                      asLines.push(""); // Append an empty string to terminate finally last line.
                      // Replace the still existing selection by resorted lines.
                      // The write command below is fast for some lines (50 or 200)
                      // but very slow for larger blocks with 5000 or more lines.
                      // UltraEdit.activeDocument.write(asLines.join("\r\n"));
                      // The alternate version using paste via a user clipboard is always
                      // very fast even for larger blocks with thousands of lines.
                      UltraEdit.selectClipboard(9);
                      UltraEdit.clipboardContent = asLines.join("\r\n");
                      UltraEdit.activeDocument.paste();
                      UltraEdit.clearClipboard();
                      UltraEdit.selectClipboard(0);
                   }
                }
                However, the script above resulted in "00" at start of a line instead of the end before Mofi modified it. Now it produces the wanted result.

                The lines are additionally sorted alphabetically before written back to the active file as requested later.

                Thanks!

                6,603548
                Grand MasterGrand Master
                6,603548

                  Mar 29, 2013#8

                  I modified the script in your post to get 00 at end of a line and pasting the modified block back to file instead of writing it back as this is faster for larger blocks.

                  24
                  Basic UserBasic User
                  24

                    Mar 29, 2013#9

                    Thanks a lot! Is working perfectly! :o