Community
    • Login

    Is there any alternative to Merge files in one plugin?

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    16 Posts 6 Posters 4.5k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • DoğancanD
      Doğancan
      last edited by

      Plugin is very slow when there are too many rows and it also only uses 20% of my CPU, can’t it use more?

      CésarC 1 Reply Last reply Reply Quote 0
      • CoisesC
        Coises
        last edited by

        There does not appear to be another merge plugin. There used to be a “Combine” plugin, but it appears to have disappeared.

        If speed with large files is a concern, my guess is that it would be best to install GnuWin CoreUtils for Windows (unless you have Linux available) and use the Paste command. Command-line processing is often a better choice than GUI applications for operations on very large files that don’t require user involvement once they’re started.

        An alternative using Notepad++ would be to make a rectangular selection enclosing all of one file and paste that into the other file; however, I suspect that will be both clumsy and slow with very large files. Another alternative would be to insert line numbers at the beginning of each line in each file, paste one after the other, sort, and then use a regular expression replacement to combine pairs of lines.

        The choice depends on what you find comfortable and how large the large files are. A couple thousand lines you can probably manage by pasting columns. Several thousand: number, paste and regex is more work, but less prone to confusing results when you can’t see what is happening because there are just too many lines to review them all. More than that — or if you’re going to have to do this repeatedly — and you’ll save time and stress in the long run by working out a command line solution.

        You could raise an issue on the GitHub repository for Merge-files-in-one. There has been no activity there since 2019, but the owner of the repository has been active elsewhere recently.

        DoğancanD 1 Reply Last reply Reply Quote 4
        • DoğancanD
          Doğancan @Coises
          last edited by Doğancan

          @Coises https://web.archive.org/web/20200726080013/http://www.scout-soft.com/combine/combine.dll
          Thanks, but it didn’t work the way I wanted.

          Alan KilbornA 1 Reply Last reply Reply Quote 0
          • Alan KilbornA
            Alan Kilborn @Doğancan
            last edited by

            @Doğancan said in Is there any alternative to Merge files in one plugin?:

            but it didn’t work the way I wanted.

            Maybe if you described what you want, someone will be able to suggest something that meets your need.

            DoğancanD 1 Reply Last reply Reply Quote 0
            • Mark OlsonM
              Mark Olson
              last edited by

              A simple Python script can paste together several thousand files with a combined size of 80MB in about 18 seconds; not sure how it scales with number of files vs. combined size. I’m not pasting the script because it’s not really a Notepad++ problem.

              Is 4-5MB/s fast enough throughput for your needs?

              1 Reply Last reply Reply Quote 1
              • Alan KilbornA
                Alan Kilborn
                last edited by

                Yea, if OP is talking about a huge amount of data, Notepad++ isn’t the right tool. Not to say it couldn’t do it (via some scripting via a plugin), but why would you do it that way?

                1 Reply Last reply Reply Quote 1
                • DoğancanD
                  Doğancan @Alan Kilborn
                  last edited by

                  Txt (1)
                  6c069b4e-32a0-4368-8391-a804418d1918-image.png
                  Txt (2)
                  2c53277e-7df8-42db-b1e8-f400101e2836-image.png

                  Result : Txt (1,2)
                  f224bed0-5d6f-47b6-823e-7375849da178-image.png

                  Mark OlsonM 1 Reply Last reply Reply Quote 0
                  • Mark OlsonM
                    Mark Olson @Doğancan
                    last edited by

                    @Doğancan

                    OK, so essentially your problem is something along the lines of:

                    • Document A has text in lines ABEFJ
                    • Document B has text in lines CD
                    • Document C has text in lines GHI

                    We want a document that contains lines ABCDEFGHIJ from Documents A, B, and C.

                    This is very different from the problem we thought we were helping you with, and it would have been nice to know earlier.

                    That said, here is a PythonScript solution (see that link for info on how to use) that can solve this problem:

                    # -*- coding: utf-8 -*-
                    # reference: https://community.notepad-plus-plus.org/topic/24872/is-there-any-alternative-to-merge-files-in-one-plugin/7?_=1693515221904
                    from __future__ import print_function
                    import re
                    from Npp import *
                    
                    __version__ = '0.1.0'
                    
                    EOLS = ('\r\n', '\r', '\n')
                    
                    def getCurrentEol():
                        return EOLS[editor.getEOLMode()]
                    
                    def main():
                        fnames = [x[0] for x in notepad.getFiles()]
                        setfnames = set(fnames)
                        fnames_str = '\r\n'.join(fnames)
                        while True:
                            fnames_chosen_str = notepad.prompt("remove the names of any files in this list that you don't want to merge", 'merge files together', fnames_str)
                            if fnames_chosen_str is None:
                                return
                            fnames_chosen = [f for f in fnames_chosen_str.split('\r\n') if f]
                            bad = False
                            for fname in fnames_chosen:
                                if fname not in setfnames:
                                    bad = True
                                    notepad.messageBox('Filename %s was not a currently open file' % fname)
                                    break
                            if not bad:
                                break
                        lines_fname_map = {}
                        for fname in fnames_chosen:
                            notepad.open(fname)
                            text = editor.getText()
                            eol = getCurrentEol()
                            lines = text.split(eol)
                            lines_fname_map[fname] = lines
                        maxlen = max(len(x) for x in lines_fname_map.values())
                        merged = []
                        collisions = {}
                        for ii in range(maxlen):
                            line_filled_by = None
                            for fname, lines in lines_fname_map.items():
                                len_ = len(lines)
                                if ii >= len_:
                                    continue
                                line = lines[ii]
                                if line:
                                    if line_filled_by:
                                        if ii not in collisions:
                                            collisions[ii] = {line_filled_by: merged[ii]}
                                        collisions[ii][fname] = line
                                    else:
                                        line_filled_by = fname
                                        merged.append(line)
                        for ii, collision in collisions.items():
                            collisions_text_list = []
                            collision_lines = list(collision.values())
                            for fname, line in collision.items():
                                existing_choice = merged[ii]
                                collisions_text_list.append('[ %s ] %s : %s' % (
                                    'X' if line == existing_choice else '',
                                    fname,
                                    line
                                ))
                            collisions_text = '\r\n'.join(collisions_text_list)
                            result = notepad.prompt('Collision at line %d. Put an X in the box of the file whose line you want to keep, then hit OK or Cancel to skip this line' % ii, 'merge collisions', collisions_text)
                            if not result:
                                continue
                            for jj, result_line in enumerate(result.split('\r\n')):
                                if re.search(r'^\s*\\[\s*\S\s*\\]', result_line):
                                    line_to_use = collision_lines[jj]
                                    merged[ii] = line_to_use
                                    break
                        notepad.new()
                        editor.setText('\r\n'.join(merged))
                        notepad.messageBox('This file contains the merger of the selected files', 'merger complete')
                        
                    if __name__ == '__main__':
                        main()
                    

                    Example usage:
                    File new 1:

                    a
                    b
                    bar
                    
                    e
                    f
                    
                    
                    
                    j
                    

                    File new 2:

                    
                    
                    c
                    d
                    

                    File new 3:

                    
                    
                    
                    
                    
                    foo
                    g
                    h
                    i
                    

                    5084a82f-dd28-4090-b74d-02b4fd677f01-image.png
                    a583dc45-310b-43b8-8149-515f4e107c93-image.png
                    659145be-ab3e-42c9-989f-a814767645af-image.png

                    Mark OlsonM 1 Reply Last reply Reply Quote 1
                    • Mark OlsonM Mark Olson referenced this topic on
                    • Mark OlsonM
                      Mark Olson @Mark Olson
                      last edited by

                      @Mark-Olson

                      That said, here is a PythonScript solution (see that link for info on how to use) that can solve this problem:

                      Improvement to the above script, with an “escape valve” added to stop processing collisions in case there are so many that going through all of them would take forever.

                      # -*- coding: utf-8 -*-
                      # reference: https://community.notepad-plus-plus.org/topic/24872/is-there-any-alternative-to-merge-files-in-one-plugin/7?_=1693515221904
                      from __future__ import print_function
                      import os
                      import re
                      from Npp import *
                      
                      __version__ = '0.2.0'
                      
                      EOLS = ('\r\n', '\r', '\n')
                      
                      def getCurrentEol():
                          return EOLS[editor.getEOLMode()]
                      
                      def main():
                          fnames = [x[0] for x in notepad.getFiles()]
                          setfnames = set(fnames)
                          fnames_str = '\r\n'.join(fnames)
                          while True:
                              fnames_chosen_str = notepad.prompt("remove the names of any files in this list that you don't want to merge", 'merge files together', fnames_str)
                              if fnames_chosen_str is None:
                                  return
                              fnames_chosen = [f for f in fnames_chosen_str.split('\r\n') if f]
                              bad = False
                              for fname in fnames_chosen:
                                  if fname not in setfnames:
                                      bad = True
                                      notepad.messageBox(
                                          'Filename %s was not a currently open file' % fname,
                                          'nonexistent filename',
                                          MESSAGEBOXFLAGS.ICONEXCLAMATION
                                      )
                                      break
                              if not bad:
                                  break
                          lines_fname_map = {}
                          for fname in fnames_chosen:
                              notepad.open(fname)
                              text = editor.getText()
                              eol = getCurrentEol()
                              lines = text.split(eol)
                              lines_fname_map[fname] = lines
                          maxlen = max(len(x) for x in lines_fname_map.values())
                          merged = []
                          collisions = {}
                          for ii in range(maxlen):
                              line_filled_by = None
                              for fname, lines in lines_fname_map.items():
                                  len_ = len(lines)
                                  if ii >= len_:
                                      continue
                                  line = lines[ii]
                                  if line:
                                      if line_filled_by:
                                          if ii not in collisions:
                                              collisions[ii] = {line_filled_by: merged[ii]}
                                          collisions[ii][fname] = line
                                      else:
                                          line_filled_by = fname
                                          merged.append(line)
                          n_collisions = len(collisions)
                          many_collisions = n_collisions > 10
                          short_fnames = {}
                          short_fname_values = set()
                          for fname in fnames_chosen:
                              fname_parts = fname.split(os.sep)
                              first_part_idx = len(fname_parts) - 1
                              short_fname = '\\'.join(fname_parts[first_part_idx:])
                              while first_part_idx >= 0 and short_fname in short_fname_values:
                                  first_part_idx -= 1
                                  short_fname = '\\'.join(fname_parts[first_part_idx:])        
                              short_fname_values.add(short_fname)
                              short_fnames[fname] = short_fname
                          for coll_ix, (ii, collision) in enumerate(collisions.items()):
                              collisions_text_list = []
                              collision_lines = list(collision.values())
                              for fname, line in collision.items():
                                  existing_choice = merged[ii]
                                  collisions_text_list.append('[ %s ] %r : %r' % (
                                      'X' if line == existing_choice else '',
                                      short_fnames[fname],
                                      line
                                  ))
                              collisions_text = '\r\n'.join(collisions_text_list)
                              result = notepad.prompt('Collision at line %d. Put an X in the box of the file whose line you want to keep, then hit OK or Cancel to skip this line' % ii, 'merge collisions', collisions_text)
                              stop_processing = False
                              if result:        
                                  for jj, result_line in enumerate(result.split('\r\n')):
                                      if re.search(r'^\s*\\[\s*\S\s*\\]', result_line):
                                          line_to_use = collision_lines[jj]
                                          merged[ii] = line_to_use
                                          break
                              else:
                                  stop_processing = True
                              remaining_colisions = n_collisions - coll_ix - 1
                              if coll_ix % 5 == 0 and remaining_colisions >= 5:
                                  mb_result = notepad.messageBox(
                                      'There are %d unresolved collisions left. Stop processing them now?' % remaining_colisions,
                                      'Many collisions left',
                                      MESSAGEBOXFLAGS.ICONQUESTION | MESSAGEBOXFLAGS.YESNO
                                  )
                                  if mb_result == MESSAGEBOXFLAGS.RESULTYES:
                                      break
                          notepad.new()
                          editor.setText('\r\n'.join(merged))
                          notepad.messageBox('This file contains the merger of the selected files', 'merger complete')
                          
                      if __name__ == '__main__':
                          main()
                      
                      DoğancanD 1 Reply Last reply Reply Quote 3
                      • Mark OlsonM Mark Olson referenced this topic on
                      • DoğancanD
                        Doğancan @Mark Olson
                        last edited by Doğancan

                        @Mark-Olson It really worked. Endless thanks .Can you publish this as a plugin so that everyone can use it ?

                        Mark OlsonM 1 Reply Last reply Reply Quote 0
                        • Mark OlsonM
                          Mark Olson @Doğancan
                          last edited by

                          @Doğancan said in Is there any alternative to Merge files in one plugin?:

                          Can you publish this as a plugin so that everyone can use it ?

                          Glad it worked! A plugin? No. PythonScript scripts have to be installed according to this link.

                          The closest thing I can provide is a Github gist.

                          DoğancanD 1 Reply Last reply Reply Quote 0
                          • DoğancanD
                            Doğancan @Mark Olson
                            last edited by

                            @Mark-Olson I thought that plugins work with python.What programming language are notepad++ plugins written in ?

                            CoisesC EkopalypseE 2 Replies Last reply Reply Quote 0
                            • CoisesC
                              Coises @Doğancan
                              last edited by

                              @Doğancan said in Is there any alternative to Merge files in one plugin?:

                              What programming language are notepad++ plugins written in ?

                              Notepad++ plugins are DLLs using a C interface, so any language that can be compiled to that could be used to write a plugin. In addition to “native” C or C++, the documentation links to API files for Ada, C#, D and Delphi.

                              Mark OlsonM 1 Reply Last reply Reply Quote 3
                              • Mark OlsonM
                                Mark Olson @Coises
                                last edited by

                                @Coises
                                …and Pascal, V, as well as PythonScript-like plugins in Lua and JavaScript.

                                1 Reply Last reply Reply Quote 2
                                • EkopalypseE
                                  Ekopalypse @Doğancan
                                  last edited by

                                  @Doğancan said in Is there any alternative to Merge files in one plugin?:

                                  @Mark-Olson I thought that plugins work with python.What programming language are notepad++ plugins written in ?

                                  So far, besides what has already been mentioned, I have written plugins in Nim, Odin, Zig, Rust and Python (using cython and cffi). So basically it boils down to the language having to be able to create a native DLL that Npp can load.

                                  1 Reply Last reply Reply Quote 4
                                  • DoğancanD Doğancan referenced this topic on
                                  • Mark OlsonM Mark Olson referenced this topic on
                                  • CésarC
                                    César @Doğancan
                                    last edited by César

                                    @Doğancan This solution worked for me (I tried it on merging HTML files succesfully):

                                    @Diego-Raguindin said in Combine Plugin Gone!?:

                                    This worked perfectly for me:

                                    Put all of the files you want to combine in the same folder. Easiest would be at root-level.
                                    Run a command prompt
                                    CD to the folder in Step 1
                                    Enter command copy *.csv filename.csv where “filename” is the desired output filename
                                    Hit enter
                                    File ‘filename.csv’ is created in the same folder
                                    

                                    https://community.notepad-plus-plus.org/post/77090

                                    1 Reply Last reply Reply Quote 0
                                    • First post
                                      Last post
                                    The Community of users of the Notepad++ text editor.
                                    Powered by NodeBB | Contributors