Combine 2 texts line by line
-
Hello, @honorata-Wisniewski, @scott-sumner and All,
I found an easier method, which does not need column numbering nor sort operation :-)) It just uses… … a regex S/R !
I, simply, assume two facts :
-
You have two tabs, in Notepad++, with the contents of
File1
andFile2
-
File1
andFile2
contain the same numbern
of lines
If so, follow these steps, below :
-
Open a new tab (
Ctrl + N
) -
Select the contents of
File1
and paste them in this new tab -
Write a dummy line as, for instance,
~~~~~~~~~~~~~~
( note that you must type in, at least, three~
characters, at the beginning of line ) -
Select the contents of
File2
and paste them, in the new tab, BELOW the~~~~~~~~~~~~~~
line -
Open the Replace dialog (
Ctrl + H
)
SEARCH
(?s)^~~~.+|(?-s)^.*(?=\R(?:.*\R){n}(^.*))
( Just replacen
with the appropriate number of lines )REPLACE
?1$0\1
OPTIONS :
Wrap Around
andRegular expression
set. All other options untickedACTION : Click on the
Replace All
buttonEt voilà ;-))
Remarks :
-
Some lines of
File1
and/orFile2
may be empty lines, without any problem -
I also noticed that
File1
may contain more lines thanFile2
. In that case the numbern
represents the number of lines inFile2
Notes on the S/R :
-
The search regex has two alternatives :
-
The
(?s)^~~~.+
which represents the range of text, from the dummy line, included, till the very end of the file, which must be deleted, at the end of the process -
The
(?-s)^.*(?=\R(?:.*\R){n}(^.*))
, matches the contents of any line, even empty, ofFile1
, if the contents of the look-ahead ( a condition )\R(?:.*\R){n}(^.*)
is true. That is to say if the current line is followed by a line-break, (\R
) then byn
complete lines, even empty in a non-capturing group ((?:.*\R){n}
) , and, finally, by the contents of the next line, even empty, stored as group 1, due to the parentheses ((^.*)
)
-
-
In replacement :
-
If group 1 exists, we rewrite the matched line ( of
File1
) ($0
), followed by the the contents of group1 (\1
) ( corresponding line inFile2
) -
If group 1 does not exist ( case of the
1st
alternative ) no text is rewritten and text from the dummy line till the end of file is just deleted
-
Here is a practical example :
Assuming
File1
contents (9
lines ) are :Beginning of Line 1 Beginning of Line 2 Beginning of Line 4 Beginning of Line 5 Beginning of Line 6 Beginning of Line 7 Beginning of Line 9
and
File2
contents (9
lines ) are :End of Line 1 End of Line 2 End of Line 3 End of Line 5 End of Line 6 End of Line 8 End of Line 9
Then the new tab contains the following text :
Beginning of Line 1 Beginning of Line 2 Beginning of Line 4 Beginning of Line 5 Beginning of Line 6 Beginning of Line 7 Beginning of Line 9 ~~~~~~~~~~~~~~~~~~~~ End of Line 1 End of Line 2 End of Line 3 End of Line 5 End of Line 6 End of Line 8 End of Line 9
And AFTER the following regex S/R :
SEARCH :
(?s)^~~~.+|(?-s)^.*(?=\R(?:.*\R){9}(^.*))
REPLACE :
?1$0\1
You should get, in the new tab, the resulting text :
Beginning of Line 1End of Line 1 Beginning of Line 2End of Line 2 End of Line 3 Beginning of Line 4 Beginning of Line 5End of Line 5 Beginning of Line 6End of Line 6 Beginning of Line 7 End of Line 8 Beginning of Line 9End of Line 9
Best Regards,
guy038
P.S. :
See, also, a similar problem, in that post :
https://notepad-plus-plus.org/community/topic/14944/macro-complex-instructions/8
-
-
Hi, @honorata-Wisniewski, @scott-sumner and All,
Oooooups ! I’ve just realized that my previous results are not exactly what Honorata would like to ! So, here is my second attempt :
So, let’s use, again, the example text :
Beginning of Line 1 Beginning of Line 2 Beginning of Line 4 Beginning of Line 5 Beginning of Line 6 Beginning of Line 7 Beginning of Line 9 ~~~~~~~~~~~~~~~~~~~~ End of Line 1 End of Line 2 End of Line 3 End of Line 5 End of Line 6 End of Line 8 End of Line 9
So, AFTER the following regex S/R :
SEARCH :
(?s)^~~~.+|(?-s)^.*\R(?=(?:.*\R){9}(^.*\R))
REPLACE :
?1$0\1
You’ll get, this time, the expected text, below :
Beginning of Line 1 End of Line 1 Beginning of Line 2 End of Line 2 End of Line 3 Beginning of Line 4 Beginning of Line 5 End of Line 5 Beginning of Line 6 End of Line 6 Beginning of Line 7 End of Line 8 Beginning of Line 9 End of Line 9
Cheers,
guy038
-
@guy038 said:
(?s)^~~~.+|(?-s)^.\R(?=(?:.\R){9}(^.*\R))
Thank you! It also works!
But there is a little nuance here. Number of lines (in your example) shall be equal 20 (not 19). Line 20 can be empty
Otherwise the last line “End of Line 9” disappear -
Hi, @honorata-Wisniewski and All,
Ah yes, I forgot to point out that the last line, of the new tab contents ( The
End of line 9
in our example ) must be followed by a line-break. If you choose the menu option View > Show Symbol > Show all characters, the last line should be displayed asEnd of line 9
CRLF ( orEnd of line 9
LF, for Unix files ) and not, simply, asEnd of line 9
Indeed, if you do not add a line-break ( the regex
\R
), the last part of my regex(^.*\R)
cannot be matched and, consequently, the overall match, for the last line, because of the lack of the End of Line characters !Best Regards,
guy038
P.S. :
-
Remenber that the quantifier
{9}
, in the regexes, represents the exact number of lines of, bothFile1
andFile2
-
The separation line must begin by, at least, the string
~~~
, even if the surrounding lines begin with some blank characters
-
-
just in case you are interested in a python script way of doing it.
from itertools import izip_longest # create a list of lines from editor1 editor1_list = editor1.getText().split() # create a list of lines from editor2 editor2_list = editor2.getText().split() #create the merged list (not really a list but an iterator) resulting_list = izip_longest(editor1_list,editor2_list, fillvalue='') # create new document notepad.new() # populate the merged list editor.setText('\n'.join('\n'.join(x) for x in resulting_list))
If the two documents do have different numbers of lines then this solution adds an empty line.
Maybe useful (?)Cheers
Claudia -
So I’m not one to try to oversell a solution I come up with, but mine was actually one that I could remember how to do if the need ever arises to do this type of 2-file merge.
While the regex based solution is cool, elegant, etc., how could one possibly remember it? One could document it or a link (to here) in a file, but then one would have to spend time searching for THAT. Same goes for the Pythonscript; nice, but I’d have to keep track of it…for this very very occasional need.
My solution did have a regex replacement component. Hard to remember that one? No, for those that are regex-worthy. Yes, for those that are not. So let’s eliminate that part (I’ve decided that the column-selection method I hinted at above is not too hard (to remember)):
To remove the leading numbers put on in the column-editor step (non-regex version):
- Move the cursor/caret to the top of the now-interleaved file with Ctrl+Home
- Invoke Edit (menu) -> Begin/End Select (a shame that this handy command has no default keycombo assigned!)
- Move the cursor/caret to the bottom of the file with Ctrl+End
- Move the caret to the LEFT side of the last digit to be removed near the start of the last line
- Press Shift+Alt+RightArrow so that the last digit to be removed becomes highlighted (note that the addition of Alt to the keycombo makes this one-character selection a “column” selection–important to the next step!
- Invoke Edit (menu) -> Begin/End Select (all of the line-leading digits to be removed are now highlighted/selected (in a “column selection”
- Tap the Delete key and BOOM GOES THE DYNAMITE–you are left with only the text you want to end up with–the interleaved files
-
Hi @Scott-sumner,
Sure that the Edit > Begin/End menu command is interesting when the start of the selection is somewhere, inside the file, but, as we need a rectangular selection from the first digit of the first line, it could be realized even more simply :-)
So, assuming you have some fixed width digit columns, at beginning of all lines of your file :
-
Move to the very beginning of the file (
Ctrl + Home
) -
Then, drag down the vertical lift, on the right side of the editor window, to get the very end of the file
-
Hold down, simultaneously, the
Alt
andShift
keys and, at the same time, left click, with the mouse, right after the last digit of the last line
=> A rectangular selection, highlights all the digits, on the left side of the editor window
-
Hit the
Delete
key, to suppress the numbers -
Hit the
Left Arrow
key, to delete the 0 column selection and move back at the very beginning of the file
Et voilà !
This post, Scott, give me the opportunity to wish you, all N++ users , contributors and @Don-HO, as well as your families,
"O-O-O-O Merry Christmas O-O-O-O"
!!!Cheers,
guy038
-
-
There are 2 reasons I like to use Begin / End Select with the keyboard instead of the mouse:
-
When you have a large file, scrolling operations with the mouse take some effort/time; keyboard operations to jump to start of file (Ctrl+Home) and end of file (Ctrl+End) are quick. In fact, Begin/End Select was probably created for keyboard users manipulating larger files.
-
With the mouse, if you have a smaller font size enabled, it is kind of hard to hit an exact spot with the mouse in a single-click. I find that as I’m also concentrating on doing Shift+Alt while doing it, it makes it slightly harder. With the keyboard I know where I have the cursor/caret before I do the modifier keycombo, so no errant spot-hitting.
Of course, it is a personal preference.
-
-
@Honorata-Wisniewski said:
Hi all!
How can I combine 2 texts (or 2 files) in notepad++ line by line?
Thus:
1 line from text1 (or file1)
1 line from text2 (or file2)
2 line from text1 (or file1)
2 line from text2 (or file2)
…
ect?Thanks!
I frequently face such a need and I usually do the following (I assure you it is more long to explicate than to do):
- I start by selecting the content of the first file with keyboard or mouse: I select it holding the Alt button on the keyboard to use the built-in N++ column selection mode;
- I copy the selected text (Ctrl+c) to the clipboard;
- Then I go to the second file at the first line;
- Hold Alt+Shift keys and I go with the mouse or the keyboard down arrow to the last row at the EOF. Now I have a multi line keyboard cursor (that is the insertion point) blinking in my file;
- I insert in the whole column previous selected a space-holder char (you can use any char that is not used into your file or even any string like “newlinehere”);
- then I go to the first line, the first char of the row positioning the insert point prior of the space-holder;
- Press Ctrl+v to paste the text from the clipboard;
- Now I set a search for the place-holder and replace with \r\n;
- Done.
Here is an animation that clarifies all steps. Unfortunately this community doesn’t accept file upload so I linked the external resource. Enjoy
-
Hi, @scott-sumner,
I agree with you, that the Begin/End select feature could be useful, dealing with large files !
BTW, here is below, my method, slightly different from yours, to combine the Begin/End select feature and the column selection mode :
Let’s start with the text, below :
1 This a small example text 2 to s><how how to do a 3 column selection with 4 the "Begin/End Sele><ct" 5 feature of Notepad++
-
Left click at the position, between the two symbols
><
, in line2
-
Execute a Edit > Begin/End Select command
-
Now, left click at the other position, between the two symbols
><
, in line4
Note that it’s the exact location where you want the column selection to be ended !
-
Hold down, simultaneously, the
Alt
andShift
keys and then hit the two keysRight Arrow
thenLeft Arrow
, to get a 0-column selection -
Execute, again, a Edit > Begin/End Select command
=> The three lines column selection, below, is created :
<how how to do n selection wit Begin/End Sele>
Cheers,
guy038
-
-
So @wonkawilly 's solution is a good one. It is often forgotten that a column/rectangular selection isn’t really rectangular if some/all of its lines end before they hit the right edge of the block. That is a key point that makes this solution viable.
One “problem” with the solution is that it relies on the user to know that the column block to be copied is wide enough to capture the longest line. If there are a lot of lines this becomes problematic as using the Begin / End Select techique discussed earlier is definitely the way to go. But doing so creates uncertainty that the column block defined by the user at the last line of the file is truly wide enough. Maybe a viable solution is to decide that a large number of columns (256?) will cover all situations likely to be encountered.
So even better than remembering how to do this technique is recording it as a macro and having it always handy on the Macro menu. I decided to give this a try. I decided to do it as 2 macros. It could be done as one macro with some extra effort…
The first macro copies all data (up to 256 columns) in the current file to the clipboard as a column block. It looks like this:
<Macro name="Copy All Lines in Column Mode (max. 256 cols.)" Ctrl="no" Alt="no" Shift="no" Key="0"> <Action type="0" message="2316" wParam="0" lParam="0" sParam="" /> <Action type="2" message="0" wParam="42020" lParam="0" sParam="" /> <Action type="0" message="2318" wParam="0" lParam="0" sParam="" />
Then REPEAT this line 256 times in the first macro:
<Action type="0" message="2429" wParam="0" lParam="0" sParam="" />
Then continue with this for the first macro:
<Action type="2" message="0" wParam="42020" lParam="0" sParam="" /> <Action type="0" message="2178" wParam="0" lParam="0" sParam="" /> <Action type="2" message="0" wParam="42002" lParam="0" sParam="" /> <Action type="0" message="2345" wParam="0" lParam="0" sParam="" /> </Macro>
The second macro merges the column-block data in the clipboard into the current file as the file’s new odd-numbered lines. It looks like this:
<Macro name="Merge in Col. Block in Clipboard as Odd Numbered Lines" Ctrl="no" Alt="no" Shift="no" Key="0"> <Action type="0" message="2316" wParam="0" lParam="0" sParam="" /> <Action type="3" message="1700" wParam="0" lParam="0" sParam="" /> <Action type="3" message="1601" wParam="0" lParam="0" sParam="^" /> <Action type="3" message="1625" wParam="0" lParam="2" sParam="" /> <Action type="3" message="1602" wParam="0" lParam="0" sParam="\xff" /> <Action type="3" message="1702" wParam="0" lParam="768" sParam="" /> <Action type="3" message="1701" wParam="0" lParam="1609" sParam="" /> <Action type="0" message="2316" wParam="0" lParam="0" sParam="" /> <Action type="0" message="2179" wParam="0" lParam="0" sParam="" /> <Action type="3" message="1700" wParam="0" lParam="0" sParam="" /> <Action type="3" message="1601" wParam="0" lParam="0" sParam="\xff" /> <Action type="3" message="1625" wParam="0" lParam="2" sParam="" /> <Action type="3" message="1602" wParam="0" lParam="0" sParam="\r\n" /> <Action type="3" message="1702" wParam="0" lParam="768" sParam="" /> <Action type="3" message="1701" wParam="0" lParam="1609" sParam="" /> <Action type="0" message="2316" wParam="0" lParam="0" sParam="" /> </Macro>
I had one problem with recording the macro I originally wanted for the second macro. I was attempting to get a zero-width column mode caret in column 1 for inserting a special character (I used hex FF as that special character) that would be replaced later with
\r\n
. Unfortunately, what was recorded into the macro for this resulted in only a non-column caret on the last line of the file. I didn’t delve too much into the macro source to see if I could work around this issue; rather I realized that a replace-all operation where one searches for^
(beginning of line) and replaces that with the desired special character would work equivalently.So an example of this whole thing in action would be:
File 1
contents:aaaaaaaaaa bbbbbbbbbbbbbbb cccccccc ddddddddd eeeeeeeeeeeeeee fffffffffffffffff
File 2
contents:11111111111111111111111 222222 3333333 444444444444 55555555 666
With
File 1
active run the first macro (“Copy All Lines in Column Mode (max. 256 cols.)”).With
File 2
active run the second macro (“Merge in Col. Block in Clipboard as Odd Numbered Lines”).File 2
contents after the merge (noteFile 1
is unchanged):aaaaaaaaaa 11111111111111111111111 bbbbbbbbbbbbbbb 222222 cccccccc 3333333 ddddddddd 444444444444 eeeeeeeeeeeeeee 55555555 fffffffffffffffff 666
-
@Fernando-Sorensen made a new post which added an alternate idea; I have linked to it for future readers of this topic, so they don’t miss the separate post.
-
@guy038 said in Combine 2 texts line by line:
(?s)
thanks for such a valuable post. its working for me. how to merge 3 files.