Script to get list of files with same or similar name

Script to get list of files with same or similar name

942
Advanced UserAdvanced User
942

    Dec 14, 2023#1

    I'm trying to write a script that could find all files inside a folder and its subfolders.
    "GetListOfFiles.js", written by Mofi, already do that.

    But how to modify it to find only files with exactly same name?
    Like this:

    Code: Select all

    d:\folder1\one file.jpg
    d:\folder2\one file.jpg
    d:\folder3\one file.jpg
    
    Extension could be disregard or not. Never mind.

    And more: how to adjust a variable to a given number of same word in sequence?
    Like this:

    If I set the number to "2" and have these files:

    Code: Select all

    d:\folder1\this is the first file.docx
    d:\folder2\The second one.mp4
    d:\folder3\first file of the folder.jpg
    d:\folder4\file without name.webp
    
    Result would be:

    Code: Select all

    d:\folder1\this is the first file.docx
    d:\folder3\first file of the folder.jpg
    Because "first file" is 2 words in sequence.

    6,634551
    Grand MasterGrand Master
    6,634551

      Dec 14, 2023#2

      For the first task use

      Code: Select all

      GetListOfFiles(0,"D:\\","one file.jpg",true);
      or if the file extension should not matter

      Code: Select all

      GetListOfFiles(0,"D:\\","one file.*",true);
      For the second task use:

      Code: Select all

      GetListOfFiles(0,"D:\\","*first file*.*",true);
      The Windows file IO functions called by UltraEdit accessing the file system makes the main job here and returns to UltraEdit the file system entries matched by the files/types wildcard pattern which of course can be also without * or ? for searching for files of which long or short name matches exactly the file search pattern.
      Best regards from an UC/UE/UES for Windows user from Austria

      942
      Advanced UserAdvanced User
      942

        Dec 14, 2023#3

        Mofi wrote:
        Dec 14, 2023
        For the first task use

        Code: Select all

        GetListOfFiles(0,"D:\\","one file.jpg",true);
        Thank you, Mofi.

        I called the function this way:

        Code: Select all

        if (GetListOfFiles(0,sParentFolderPath,"*.*",true))
        {
           UltraEdit.activeDocument.top();
           UltraEdit.activeDocument.findReplace.mode=0;
           UltraEdit.activeDocument.findReplace.matchCase=false;
           UltraEdit.activeDocument.findReplace.matchWord=false;
           UltraEdit.activeDocument.findReplace.regExp=false;
           UltraEdit.activeDocument.findReplace.searchDown=true;
           UltraEdit.activeDocument.findReplace.searchInColumn=false;
           UltraEdit.activeDocument.findReplace.preserveCase=false;
           UltraEdit.activeDocument.findReplace.replaceAll=true;
           UltraEdit.activeDocument.findReplace.replaceInAllOpen=false;
           UltraEdit.activeDocument.findReplace.replace(sParentFolderPath+"*.*\r\n","");
        }
        And I got a list of all files with full path in specified directory tree.

        But how to get the list with only files that has the same same?

        If there are 2 or more duplicates, files will be listed
        If there is only 1 unique name of each file, they will not be listed.
        In other words, if there is no duplicated names at directory tree, the list would be empty.

        6,634551
        Grand MasterGrand Master
        6,634551

          Dec 14, 2023#4

          I have understood now better what you really want. I can offer two solutions for getting a list of duplicate file names which UltraCompare and UltraFinder can also output.

          The first one does nothing in memory of the JavaScript core engine which makes it possible finding duplicate file names even in a list of millions of file names. The disadvantage is that several undo records are created during the script execution. This solution sorts the file names which can be an advantage or a disadvantage.

          Code: Select all

          if (GetListOfFiles(0,"D:\\","*",true))
          {
             // Define the parameters for a case-insensitive Perl regular expression
             // replace all executed from top on the entire find results file with
             // the file names of all found files.
             UltraEdit.perlReOn();
             UltraEdit.activeDocument.findReplace.mode=0;
             UltraEdit.activeDocument.findReplace.matchCase=false;
             UltraEdit.activeDocument.findReplace.matchWord=false;
             UltraEdit.activeDocument.findReplace.regExp=true;
             UltraEdit.activeDocument.findReplace.searchDown=true;
             if (typeof(UltraEdit.activeDocument.findReplace.searchInColumn) == "boolean")
             {
                UltraEdit.activeDocument.findReplace.searchInColumn=false;
             }
             UltraEdit.activeDocument.findReplace.preserveCase=false;
             UltraEdit.activeDocument.findReplace.replaceAll=true;
             UltraEdit.activeDocument.findReplace.replaceInAllOpen=false;
             
             // The expression matches everything from beginning of a line to last backslash
             // by the expression in first marking group which is the path of a file name
             // and everything after the last backslash which is the name of the file by
             // the expression in second marking group and exchange the name of file and
             // file path with inserting a horizontal tab character between them.
             UltraEdit.activeDocument.findReplace.replace("^(.+\\\\)(.*)$","\\2\\t\\1");
          
             // Sort the list of file names case-insensitive.
             UltraEdit.activeDocument.sortAsc(2,true,false,1,-1);
          
             // Switch the clipboard to user clipboard 9 and clear it.
             UltraEdit.selectClipboard(9);
             UltraEdit.clearClipboard();
          
             // Search with a case-insensitive Perl regular expression executed in a loop
             // for at least two or more lines beginning with same file name and copy them
             // to the user clipboard 9. These are the files with identical file name.
             while (UltraEdit.activeDocument.findReplace.find("^([^\\t]+)\\t.+\\r\\n(?:\\1\\t.+\\r\\n)+"))
             {
                UltraEdit.activeDocument.copyAppend();
             }
          
             // Select the entire file names list, delete it, and paste the list
             // of duplicate file names in user clipboard 9 into the results file.
             UltraEdit.activeDocument.selectAll();
             UltraEdit.activeDocument.deleteText();
             UltraEdit.activeDocument.paste();
          
             // Clear user clipboard 9 and select the operating system clipboard.
             UltraEdit.clearClipboard();
             UltraEdit.selectClipboard(0);
          
             // Move caret to top of the file and run a Perl regular expression
             // replace to move the file names back after last backslash.
             UltraEdit.activeDocument.top();
             UltraEdit.activeDocument.findReplace.replace("^([^\\t]+)\\t(.+)$","\\2\\1");
          }
          
          The second solution makes as much as possible in memory of the JavaScript core interpreter using JavaScript core functions. It produced less undo records. But it cannot be used for millions of file names as the memory of the JavaScript core interpreter is limited nearly independent on free available RAM of the PC. The duplicate file names are not sorted by file name in this case. There must be additionally added the function GetNameOfFile to the script file used here instead of a regular expression to get the name of each file without path.

          Code: Select all

          if (GetListOfFiles(0,"D:\\","*",true))
          {
             // Load the file names list as an array of strings into memory.
             UltraEdit.activeDocument.selectAll();
             var asFullFileNames = UltraEdit.activeDocument.selection.split("\r\n");
             // The last file name is an empty string and is removed for that reason.
             asFullFileNames.pop();
          
             // Create one more array for name of the files without path with all
             // letters converted to lowercase for a case-insensitive comparison
             // of the names later for finding duplicate file names.
             var asFileNames = new Array(asFullFileNames.length);
             var nFileNameIndex;
             for (nFileNameIndex = 0; nFileNameIndex < asFullFileNames.length; ++nFileNameIndex)
             {
                asFileNames[nFileNameIndex] = GetNameOfFile(asFullFileNames[nFileNameIndex]).toLowerCase();
             }
          
             // Create a new array for the list of duplicate file names.
             var asDuplicateFiles = [];
          
             // Compare each file name without path with each other file name
             // without path below in the list until all file names are compared
             // with all other file names.
             for (nFileNameIndex = 0; nFileNameIndex < asFullFileNames.length; ++nFileNameIndex)
             {
                var bDuplicate = false;
                var nCompareIndex = nFileNameIndex + 1;
                while (nCompareIndex < asFileNames.length)
                {
                   // This string comparison is case-sensitive which is the reason
                   // for using above the function toLowerCase for each file name.
                   if (asFileNames[nFileNameIndex] != asFileNames[nCompareIndex])
                   {
                      nCompareIndex++;
                   }
                   else
                   {
                      // Is that the first time that the file name was found
                      // a second time in the list of file names?
                      if (!bDuplicate)
                      {
                         // Append the full file name to the array of duplicate
                         // file names first.
                         asDuplicateFiles.push(asFullFileNames[nFileNameIndex]);
                         bDuplicate = true;
                      }
                      // Now append the duplicate file name in another directory
                      // and remove that file name from both file name arrays to
                      // avoid processing duplicate file names more than once.
                      asDuplicateFiles.push(asFullFileNames[nCompareIndex]);
                      asFullFileNames.splice(nCompareIndex,1);
                      asFileNames.splice(nCompareIndex,1);
                   }
                }
             }
          
             // Are any duplicate file names found?
             if (asDuplicateFiles.length)
             {
                // Append an empty string to the list of duplicate file names for
                // having the last line in the results file finally also with the
                // DOS/Windows line termination.
                asDuplicateFiles.push("");
                // Join the array of duplicate file names with carriage return and
                // line-feed and write them over the selection in the results file.
                UltraEdit.activeDocument.write(asDuplicateFiles.join("\r\n"));
             }
             else
             {
                // Delete everything in the results file on no duplicate file names.
                UltraEdit.activeDocument.deleteText();
             }
          }
          
          Best regards from an UC/UE/UES for Windows user from Austria

          942
          Advanced UserAdvanced User
          942

            Dec 15, 2023#5

            Both solutions work fine. They list the files with same name, as requested.

            But I think we can improve our solutions.
            How to list only the files with part of the name the same?

            Explaining.
            When I copy some file in the same folder, Directory Opus, Windows Explorer or other file manager puts some extra strings to the name.

            Example:
            Filename is "This is my file.docx".
            When I copy it to the same folder, its copy is:

            "Copy (1) of This is my file.docx"
            or
            "This is my file (1).docx"

            How to list files when 2 or more words in sequence (in a row) is the same?

            If I have this folder:

            Code: Select all

            F:\Thunder\abook.mab
            F:\Thunder\Copy (1) of extensions of database.rdf
            F:\Thunder\Copy (1) of mimeTypes from database.rdf
            F:\Thunder\history.mab
            F:\Thunder\extensions of database.rdf
            F:\Thunder\xpti.dat
            F:\Thunder\compreg.dat
            F:\Thunder\signons.sqlite
            F:\Thunder\mimeTypes from database.rdf
            F:\Thunder\localstore.rdf
            
            Result list would be:

            Code: Select all

            F:\Thunder\Copy (1) of extensions of database.rdf
            F:\Thunder\Copy (1) of mimeTypes from database.rdf
            F:\Thunder\extensions of database.rdf
            F:\Thunder\mimeTypes from database.rdf
            Because they have same words in sequence.

            6,634551
            Grand MasterGrand Master
            6,634551

              Dec 15, 2023#6

              The second solution can be enhanced with a more smart file name comparison to find duplicate files by similarities in file name. There must be additionally added the three functions GetFileExt, GetFileName and GetNameOfFile to the script file containing already the function GetListOfFiles and the main code as posted below.

              Code: Select all

              if (GetListOfFiles(0,"F:\\Thunder\\","*",false))
              {
                 // Load the file names list as an array of strings into memory.
                 UltraEdit.activeDocument.selectAll();
                 var asFullFileNames = UltraEdit.activeDocument.selection.split("\r\n");
                 // The last file name is an empty string and is removed for that reason.
                 asFullFileNames.pop();
              
                 // Create one more array for name of the files without path with all
                 // letters converted to lowercase for a case-insensitive comparison
                 // of the names later for finding duplicate file names.
                 var asFileNames = new Array(asFullFileNames.length);
                 var nFileNameIndex;
                 for (nFileNameIndex = 0; nFileNameIndex < asFullFileNames.length; ++nFileNameIndex)
                 {
                    asFileNames[nFileNameIndex] = GetNameOfFile(asFullFileNames[nFileNameIndex]).toLowerCase();
                 }
              
                 // Create a new array for the list of duplicate file names.
                 var asDuplicateFiles = [];
                 var nLength1;
                 var nLength2;
                 var sFileName1;
                 var sFileName2;
                 var sShorterFileName;
              
                 // Compare each file name without path with each other file name
                 // without path below in the list until all file names are compared
                 // with all other file names.
                 for (nFileNameIndex = 0; nFileNameIndex < asFullFileNames.length; ++nFileNameIndex)
                 {
                    var bDuplicate = false;
                    var nCompareIndex = nFileNameIndex + 1;
                    sFileName1 = asFileNames[nFileNameIndex];
                    nLength1 = sFileName1.length;
                    while (nCompareIndex < asFileNames.length)
                    {
                       sFileName2 = asFileNames[nCompareIndex];
                       nLength2 = sFileName2.length;
                       // The string comparisons are case-sensitive which is the reason
                       // for using above the toLowerCase function for each file name.
                       // The two file names are simply compared only if the length of
                       // both file names is identical. Otherwise more smart file name
                       // comparisons are done by comparing just the shorter file name
                       // with the end of the longer file name and if no match the shorter
                       // file name without its file extension with the beginning of the
                       // longer file name to identify files with similar file names.
                       // The file extensions must be identical in any case.
                       if (nLength1 < nLength2)
                       {
                          if (sFileName1 != sFileName2.substr(nLength2 - nLength1))
                          {
                             sShorterFileName = GetFileName(sFileName1);
                             if (sShorterFileName != sFileName2.substr(0,sShorterFileName.length))
                             {
                                nCompareIndex++;
                                continue;
                             }
                             if (GetFileExt(sFileName1) != GetFileExt(sFileName2))
                             {
                                nCompareIndex++;
                                continue;
                             }
                          }
                       }
                       else if (nLength1 > nLength2)
                       {
                          if (sFileName1.substr(nLength1 - nLength2) != sFileName2)
                          {
                             sShorterFileName = GetFileName(sFileName2);
                             if (sShorterFileName != sFileName1.substr(0,sShorterFileName.length))
                             {
                                nCompareIndex++;
                                continue;
                             }
                             if (GetFileExt(sFileName1) != GetFileExt(sFileName2))
                             {
                                nCompareIndex++;
                                continue;
                             }
                          }
                       }
                       else if (sFileName1 != sFileName2)
                       {
                          nCompareIndex++;
                          continue;
                       }
                       // Is that the first time that the file name was found
                       // a second time in the list of file names?
                       if (!bDuplicate)
                       {
                          // Append the full file name to the array of duplicate
                          // file names first.
                          asDuplicateFiles.push(asFullFileNames[nFileNameIndex]);
                          bDuplicate = true;
                       }
                       // Now append the similar or duplicate file name in another directory
                       // and remove that file name from both file name arrays to avoid
                       // processing similar and duplicate file names more than once.
                       asDuplicateFiles.push(asFullFileNames[nCompareIndex]);
                       asFullFileNames.splice(nCompareIndex,1);
                       asFileNames.splice(nCompareIndex,1);
                    }
                 }
              
                 // Are any duplicate or similar file names found?
                 if (asDuplicateFiles.length)
                 {
                    // Append an empty string to the list of duplicate/similar file names
                    // for having the last line in the results file finally also with the
                    // DOS/Windows line termination.
                    asDuplicateFiles.push("");
                    // Join the array of duplicate/similar file names with carriage return
                    // and line-feed and write them over the selection in the results file.
                    UltraEdit.activeDocument.write(asDuplicateFiles.join("\r\n"));
                 }
                 else
                 {
                    // Delete everything in the results file on no duplicate/similar file names.
                    UltraEdit.activeDocument.deleteText();
                 }
              }
              
              Best regards from an UC/UE/UES for Windows user from Austria

              942
              Advanced UserAdvanced User
              942

                Dec 15, 2023#7

                I copied GetListOfFiles, GetFileExt, GetFileName and GetNameOfFile to the script file.

                As it is now, it's OK. But I think it will not discover ALL similar files.

                I got the result below after applied the script:

                Code: Select all

                F:\tests\addons.json
                F:\tests\Copy of addons.json
                F:\tests\content-prefs.sqlite
                F:\tests\New Folder\content-prefs.sqlite
                F:\tests\Copy of mimeTypes.rdf
                F:\tests\mimeTypes.rdf
                F:\tests\New Folder (2)\Copy of mimeTypes.rdf
                F:\tests\Copy of search.json
                F:\tests\search.json
                F:\tests\New Folder (2)\Copy of search.json
                F:\tests\formhistory.sqlite
                F:\tests\New Folder\formhistory.sqlite
                But the correct result would be:

                Code: Select all

                F:\tests\addons.json
                F:\tests\Copy of addons.json
                F:\tests\content-prefs.sqlite
                F:\tests\New Folder\content-prefs.sqlite
                F:\tests\Copy of mimeTypes.rdf
                F:\tests\Copy (2) of mimeTypes.rdf
                F:\tests\mimeTypes.rdf
                F:\tests\New Folder (2)\Copy of mimeTypes.rdf
                F:\tests\Copy of search.json
                F:\tests\Copy (2) of search.json
                F:\tests\search.json
                F:\tests\New Folder (2)\Copy of search.json
                F:\tests\formhistory.sqlite
                F:\tests\New Folder\formhistory.sqlite
                It misses "Copy (2) of mimeTypes.rdf" and "Copy (2) of search.json".

                The directory tree for this example is attached as a RAR file.
                Below is a plain view of all files inside root and subfolders.

                Tests.png (21.83KiB)

                This is the directory tree for tests:

                Tests.rar (30.51 KiB)   0

                6,634551
                Grand MasterGrand Master
                6,634551

                  Dec 16, 2023#8

                  Here is a once more extended script code which handles also the last test case by sorting first the full file names list according to length of names of the files from shortest to longest.

                  Code: Select all

                  function SortFileNamesByLength (sFullFileName1, sFullFileName2)
                  {
                     var sNameFile1 = GetNameOfFile(sFullFileName1);
                     var sNameFile2 = GetNameOfFile(sFullFileName2);
                     if (sNameFile1.length == sNameFile2.length)
                     {
                        return sFullFileName1.length - sFullFileName2.length;
                     }
                     return sNameFile1.length - sNameFile2.length;
                  }
                  
                  if (GetListOfFiles(0,"F:\\tests\\","*",true))
                  {
                     // Load the file names list as an array of strings into memory.
                     UltraEdit.activeDocument.selectAll();
                     var asFullFileNames = UltraEdit.activeDocument.selection.split("\r\n");
                     // The last file name is an empty string and is removed for that reason.
                     asFullFileNames.pop();
                     // Sort the file names list based on length of the name of each file without path.
                     asFullFileNames.sort(SortFileNamesByLength);
                  
                     // Create one more array for name of the files without path with all
                     // letters converted to lowercase for a case-insensitive comparison
                     // of the names later for finding duplicate file names.
                     var asFileNames = new Array(asFullFileNames.length);
                     var nFileNameIndex;
                     for (nFileNameIndex = 0; nFileNameIndex < asFullFileNames.length; ++nFileNameIndex)
                     {
                        asFileNames[nFileNameIndex] = GetNameOfFile(asFullFileNames[nFileNameIndex]).toLowerCase();
                     }
                  
                     // Create a new array for the list of duplicate file names.
                     var asDuplicateFiles = [];
                     var nLength1;
                     var nLength2;
                     var sFileName1;
                     var sFileName2;
                     var sShorterFileName;
                  
                     // Compare each file name without path with each other file name
                     // without path below in the list until all file names are compared
                     // with all other file names.
                     for (nFileNameIndex = 0; nFileNameIndex < asFullFileNames.length; ++nFileNameIndex)
                     {
                        var bDuplicate = false;
                        var nCompareIndex = nFileNameIndex + 1;
                        sFileName1 = asFileNames[nFileNameIndex];
                        nLength1 = sFileName1.length;
                        while (nCompareIndex < asFileNames.length)
                        {
                           sFileName2 = asFileNames[nCompareIndex];
                           nLength2 = sFileName2.length;
                           // The string comparisons are case-sensitive which is the reason
                           // for using above the toLowerCase function for each file name.
                           // The two file names are simply compared only if the length of
                           // both file names is identical. Otherwise more smart file name
                           // comparisons are done by comparing just the shorter file name
                           // with the end of the longer file name and if no match the shorter
                           // file name without its file extension with the beginning of the
                           // longer file name to identify files with similar file names.
                           // The file extensions must be identical in any case.
                           if (nLength1 < nLength2)
                           {
                              if (sFileName1 != sFileName2.substr(nLength2 - nLength1))
                              {
                                 sShorterFileName = GetFileName(sFileName1);
                                 if (sShorterFileName != sFileName2.substr(0,sShorterFileName.length))
                                 {
                                    nCompareIndex++;
                                    continue;
                                 }
                                 if (GetFileExt(sFileName1) != GetFileExt(sFileName2))
                                 {
                                    nCompareIndex++;
                                    continue;
                                 }
                              }
                           }
                           else if (sFileName1 != sFileName2)
                           {
                              nCompareIndex++;
                              continue;
                           }
                           // Is that the first time that the file name was found
                           // a second time in the list of file names?
                           if (!bDuplicate)
                           {
                              // Append the full file name to the array of duplicate
                              // file names first.
                              asDuplicateFiles.push(asFullFileNames[nFileNameIndex]);
                              bDuplicate = true;
                           }
                           // Now append the similar or duplicate file name in another directory
                           // and remove that file name from both file name arrays to avoid
                           // processing similar and duplicate file names more than once.
                           asDuplicateFiles.push(asFullFileNames[nCompareIndex]);
                           asFullFileNames.splice(nCompareIndex,1);
                           asFileNames.splice(nCompareIndex,1);
                        }
                     }
                  
                     // Are any duplicate or similar file names found?
                     if (asDuplicateFiles.length)
                     {
                        // Append an empty string to the list of duplicate/similar file names
                        // for having the last line in the results file finally also with the
                        // DOS/Windows line termination.
                        asDuplicateFiles.push("");
                        // Join the array of duplicate/similar file names with carriage return
                        // and line-feed and write them over the selection in the results file.
                        UltraEdit.activeDocument.write(asDuplicateFiles.join("\r\n"));
                     }
                     else
                     {
                        // Delete everything in the results file on no duplicate/similar file names.
                        UltraEdit.activeDocument.deleteText();
                     }
                  }
                  
                  Best regards from an UC/UE/UES for Windows user from Austria

                  942
                  Advanced UserAdvanced User
                  942

                    Dec 16, 2023#9

                    Mofi, I apreciate your time and attention for my thread.
                    Your scripts are always of the highest quality, well commented and written.
                    Thank you.

                    Doing some testing, I noticed that now it captures the "Copy of..." prefix of filenames accordingly.
                    Good.

                    But I can't see it matching words after the first ones in the filename.
                    I mean, like this example below:

                    If I have:

                    Code: Select all

                    F:\tests\Satoshi Nakamoto created Bitcoin in 2009.docx
                    F:\tests\He mysteriously vanished in 2011.txt
                    F:\tests\makes the digital currency seem almost mystical.txt
                    F:\tests\No interference, no regulation and no surveillance.txt
                    F:\tests\Bitcoin guru mysteriously vanished.txt
                    F:\tests\Digital currency seem mystical.txt
                    The list of similar names would be:

                    Code: Select all

                    1. F:\tests\He mysteriously vanished in 2011.txt
                    2. F:\tests\Bitcoin guru mysteriously vanished.txt
                    3. F:\tests\makes the digital currency seem almost mystical.txt
                    4. F:\tests\Digital currency seem mystical.txt
                    (numbers added just to explain, as below)

                    Because:
                    1 and 2 has "mysteriously vanished" in sequence and
                    3 and 4 has "digital currency" in sequence

                    If I run the last version of the script, result is empty.

                    Better if the script could get all similarities with 3 or less words in sequence, no matter its position in filename.

                    Reading the last script, I could see that the core of comparison is right here:

                    Code: Select all

                    for (nFileNameIndex = 0; nFileNameIndex < asFullFileNames.length; ++nFileNameIndex)
                    {
                       var bDuplicate = false;
                       var nCompareIndex = nFileNameIndex + 1;
                       sFileName1 = asFileNames[nFileNameIndex];
                       nLength1 = sFileName1.length;
                       while (nCompareIndex < asFileNames.length)
                       {
                          sFileName2 = asFileNames[nCompareIndex];
                          nLength2 = sFileName2.length;
                          // The string comparisons are case-sensitive which is the reason
                          // for using above the toLowerCase function for each file name.
                          // The two file names are simply compared only if the length of
                          // both file names is identical. Otherwise more smart file name
                          // comparisons are done by comparing just the shorter file name
                          // with the end of the longer file name and if no match the shorter
                          // file name without its file extension with the beginning of the
                          // longer file name to identify files with similar file names.
                          // The file extensions must be identical in any case.
                          if (nLength1 < nLength2)
                          {
                             if (sFileName1 != sFileName2.substr(nLength2 - nLength1))
                             {
                                sShorterFileName = GetFileName(sFileName1);
                                if (sShorterFileName != sFileName2.substr(0,sShorterFileName.length))
                                {
                                   nCompareIndex++;
                                   continue;
                                }
                                if (GetFileExt(sFileName1) != GetFileExt(sFileName2))
                                {
                                   nCompareIndex++;
                                   continue;
                                }
                             }
                          }
                          else if (sFileName1 != sFileName2)
                          {
                             nCompareIndex++;
                             continue;
                          }
                          // Is that the first time that the file name was found
                          // a second time in the list of file names?
                          if (!bDuplicate)
                          {
                             // Append the full file name to the array of duplicate
                             // file names first.
                             asDuplicateFiles.push(asFullFileNames[nFileNameIndex]);
                             bDuplicate = true;
                          }
                          // Now append the similar or duplicate file name in another directory
                          // and remove that file name from both file name arrays to avoid
                          // processing similar and duplicate file names more than once.
                          asDuplicateFiles.push(asFullFileNames[nCompareIndex]);
                          asFullFileNames.splice(nCompareIndex,1);
                          asFileNames.splice(nCompareIndex,1);
                       }
                    }
                    Unfortunately, it's beyond my programming skills.

                    So, if you could improve it to get all similarities with 3 or less words in sequence, no matter its position in filename, it'd be great.

                    Below, I attached a directory tree for tests.

                    tests.rar (3.79 KiB)   0

                    6,634551
                    Grand MasterGrand Master
                    6,634551

                      Dec 16, 2023#10

                      I will not write one more solution. I lost my motivation on this project. Improve the code by yourself to your requirements. Hint: The script must split up each file name into a list of words and compare the two words lists and if the number of matching words is greater or equal X then the file names could be interpreted as similar according to your requirements.
                      Best regards from an UC/UE/UES for Windows user from Austria

                      942
                      Advanced UserAdvanced User
                      942

                        Dec 16, 2023#11

                        It's understandable.

                        Thank you.