Is there any alternative to Merge files in one plugin?
-
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?
-
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?
-
Txt (1)
Txt (2)
Result : Txt (1,2)
-
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:
Filenew 1
:a b bar e f j
File
new 2
:c d
File
new 3
:foo g h i
- Document A has text in lines
-
-
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()
-
-
@Mark-Olson It really worked. Endless thanks .Can you publish this as a plugin so that everyone can use it ?
-
@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.
-
@Mark-Olson I thought that plugins work with python.What programming language are notepad++ plugins written in ?
-
@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.
-
@Coises
…and Pascal, V, as well as PythonScript-like plugins in Lua and JavaScript. -
@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.
-
-
-
@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