Combine 2 texts line by line



  • 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!



  • @Honorata-Wisniewski

    Definitely go with two files, file1 and file2…not sure what text1 and text2 means anyway. :-D

    In file1, move the caret/cursor to the very top of the file. Press Alt+c to invoke the column-editor; set it up this way and then press OK:

    Imgur

    Repeat the same series of actions for file2.

    Copy complete text of file2 into file1 below file1’s existing text. Or better, move the text of both files into a 3rd editing tab, just be sure to have the file1 contents above the file2 data.

    In the file with the combined data, do a line sort ascending operation from the Edit (menu) -> Line Operations… choices.

    To remove the leading numbers put on in the column-editor step by the following:

    Invoke the Replace dialog (Ctrl+h).

    Find-what zone: (?-s)^.{4}(.*?\R) where 4 is just an example–use how many ever digits you need to remove from the start of your lines
    Replace-with zone: \1
    Tick the Wrap around box
    Set the Search mode to Regular Expression
    Press the Replace All button



  • Thank you very much!

    It worked!!!

    It’s quite a complicated way (thought it should be simple), but it worked!



  • @Honorata-Wisniewski

    It is not a very commonly needed thing to do, so it is “complicated”.

    You can avoid the Replace All operation by using the Begin/End Select function to select the leading numbers to remove, but that is tougher to explain for column mode use (which would be needed here–assuming you have a lot of lines of data); it does simplify it a bit, though.



  • 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 and File2

    • File1 and File2 contain the same number n 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 replace n with the appropriate number of lines )

    REPLACE ?1$0\1

    OPTIONS : Wrap Around and Regular expression set. All other options unticked

    ACTION : Click on the Replace All button

    Et voilà ;-))


    Remarks :

    • Some lines of File1 and/or File2 may be empty lines, without any problem

    • I also noticed that File1 may contain more lines than File2. In that case the number n represents the number of lines in File2

    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, of File1, 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 by n 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 in File2 )

      • 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 as End of line 9CRLF ( or End of line 9LF, for Unix files ) and not, simply, as End 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, both File1 and File2

    • The separation line must begin by, at least, the string ~~~, even if the surrounding lines begin with some blank characters



  • @Honorata-Wisniewski

    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 and Shift 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



  • @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):

    1. 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;
    2. I copy the selected text (Ctrl+c) to the clipboard;
    3. Then I go to the second file at the first line;
    4. 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;
    5. 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”);
    6. then I go to the first line, the first char of the row positioning the insert point prior of the space-holder;
    7. Press Ctrl+v to paste the text from the clipboard;
    8. Now I set a search for the place-holder and replace with \r\n;
    9. 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 line 2

    • Execute a Edit > Begin/End Select command

    • Now, left click at the other position, between the two symbols ><, in line 4

    Note that it’s the exact location where you want the column selection to be ended !

    • Hold down, simultaneously, the Alt and Shift keys and then hit the two keys Right Arrow then Left 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 (note File 1 is unchanged):

    aaaaaaaaaa
    11111111111111111111111
    bbbbbbbbbbbbbbb
    222222
    cccccccc
    3333333
    ddddddddd
    444444444444
    eeeeeeeeeeeeeee
    55555555
    fffffffffffffffff
    666

Log in to reply