Swap a line with another












3















I have the file



Line 1
Line 2 MATCH
Line 3
Line 4
Line 1
Line 2 MATCH
Line 3
Line 4


And I want to swap the line with "MATCH" and "Line 1" for every case. I tried to search in other questions, but those move the line with the match to the last line and I don't understand so well the code to remake my version for a final output like:



Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4









share|improve this question























  • Is the line with "MATCH" always line two, hence to be swapped with the line before it?

    – Sparhawk
    Feb 17 at 20:53











  • @Sparhawk Yes, it is.

    – TheAsker
    Feb 17 at 20:55











  • @don_crissti but in the answer provided there, they only swap the line N with the line below. For swap line N with the line above, they swap the Line N-1 with the line below. There is some way to swap with the line above based on a pattern?

    – TheAsker
    Feb 17 at 21:11
















3















I have the file



Line 1
Line 2 MATCH
Line 3
Line 4
Line 1
Line 2 MATCH
Line 3
Line 4


And I want to swap the line with "MATCH" and "Line 1" for every case. I tried to search in other questions, but those move the line with the match to the last line and I don't understand so well the code to remake my version for a final output like:



Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4









share|improve this question























  • Is the line with "MATCH" always line two, hence to be swapped with the line before it?

    – Sparhawk
    Feb 17 at 20:53











  • @Sparhawk Yes, it is.

    – TheAsker
    Feb 17 at 20:55











  • @don_crissti but in the answer provided there, they only swap the line N with the line below. For swap line N with the line above, they swap the Line N-1 with the line below. There is some way to swap with the line above based on a pattern?

    – TheAsker
    Feb 17 at 21:11














3












3








3








I have the file



Line 1
Line 2 MATCH
Line 3
Line 4
Line 1
Line 2 MATCH
Line 3
Line 4


And I want to swap the line with "MATCH" and "Line 1" for every case. I tried to search in other questions, but those move the line with the match to the last line and I don't understand so well the code to remake my version for a final output like:



Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4









share|improve this question














I have the file



Line 1
Line 2 MATCH
Line 3
Line 4
Line 1
Line 2 MATCH
Line 3
Line 4


And I want to swap the line with "MATCH" and "Line 1" for every case. I tried to search in other questions, but those move the line with the match to the last line and I don't understand so well the code to remake my version for a final output like:



Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4






text-processing sed






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 17 at 20:47









TheAskerTheAsker

182




182













  • Is the line with "MATCH" always line two, hence to be swapped with the line before it?

    – Sparhawk
    Feb 17 at 20:53











  • @Sparhawk Yes, it is.

    – TheAsker
    Feb 17 at 20:55











  • @don_crissti but in the answer provided there, they only swap the line N with the line below. For swap line N with the line above, they swap the Line N-1 with the line below. There is some way to swap with the line above based on a pattern?

    – TheAsker
    Feb 17 at 21:11



















  • Is the line with "MATCH" always line two, hence to be swapped with the line before it?

    – Sparhawk
    Feb 17 at 20:53











  • @Sparhawk Yes, it is.

    – TheAsker
    Feb 17 at 20:55











  • @don_crissti but in the answer provided there, they only swap the line N with the line below. For swap line N with the line above, they swap the Line N-1 with the line below. There is some way to swap with the line above based on a pattern?

    – TheAsker
    Feb 17 at 21:11

















Is the line with "MATCH" always line two, hence to be swapped with the line before it?

– Sparhawk
Feb 17 at 20:53





Is the line with "MATCH" always line two, hence to be swapped with the line before it?

– Sparhawk
Feb 17 at 20:53













@Sparhawk Yes, it is.

– TheAsker
Feb 17 at 20:55





@Sparhawk Yes, it is.

– TheAsker
Feb 17 at 20:55













@don_crissti but in the answer provided there, they only swap the line N with the line below. For swap line N with the line above, they swap the Line N-1 with the line below. There is some way to swap with the line above based on a pattern?

– TheAsker
Feb 17 at 21:11





@don_crissti but in the answer provided there, they only swap the line N with the line below. For swap line N with the line above, they swap the Line N-1 with the line below. There is some way to swap with the line above based on a pattern?

– TheAsker
Feb 17 at 21:11










5 Answers
5






active

oldest

votes


















2














If the idea is to swap the MATCH line with the immediately preceding one, then something like this would do:



$ awk '!/MATCH/ { if (NR > 1) print prev; prev=$0} 
/MATCH/ {print $0;}
END {print prev}' < file
Line 2 MATCH
Line 1
Line 3
Line 4
Line 2 MATCH
Line 1
Line 3
Line 4


The script holds the previous line in prev, printing and updating it on the non-matching lines. On lines matching the pattern, it prints the current line, leaving the previous in the variable to be printed next.



Special cases for the first line (NR==1) when there's no previous line to print, and for the END when we print the held line.






share|improve this answer































    3














    Using ed:



    $ printf 'g/MATCH/m-2n,pn' | ed -s file
    Line 2 MATCH
    Line 1
    Line 3
    Line 4
    Line 2 MATCH
    Line 1
    Line 3
    Line 4


    The m command moves the current line after to the subsequent target address. Here, we find all lines matching MATCH (it's the g in front of the regular expression that makes this a "global" operation), and for each line move it one line up (to "after the line two lines up"). The effect is that the MATCH lines swap places with the immediately preceding lines.



    The final ,p in the editing script just displays the modified editing buffer. This could be changed to something like wq to write the changed editing buffer back to the original file.



    Note that using ed for editing files might look neat, but is not recommended for large files as the whole file is read into memory.






    share|improve this answer

































      1














      Using sed with a N;P;D cycle:



      sed -e '$!N;s/(Line 1)(n)(.*MATCH.*)/321/;t' -e 'P;D' infile


      This will swap only if the line with MATCH is preceded by Line 1: the t without label branches to the end of script if successful and so it avoids another swap if any Line 1 is followed by consecutive lines with MATCH. Adjust the regex for any leading/trailing blanks.






      share|improve this answer































        1














        Using sed editor, we can swap two lines one of which contains Match keyword with the one preceding it.



         $ sed -e '
        /MATCH/!{
        x;1!p;$!d;g;q
        }
        $G
        ' input.txt

        Line 2 MATCH
        Line 1
        Line 3
        Line 4
        Line 2 MATCH
        Line 1
        Line 3
        Line 4





        share|improve this answer































          -1














          sed "s/line 2 match//g"|sed "s/line 1/line 2 matchn&/g"



          Above command worked fine






          share|improve this answer



















          • 2





            The lines with MATCH should swap places with the preceding lines.

            – Kusalananda
            Feb 17 at 23:19











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "106"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501234%2fswap-a-line-with-another%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          5 Answers
          5






          active

          oldest

          votes








          5 Answers
          5






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          If the idea is to swap the MATCH line with the immediately preceding one, then something like this would do:



          $ awk '!/MATCH/ { if (NR > 1) print prev; prev=$0} 
          /MATCH/ {print $0;}
          END {print prev}' < file
          Line 2 MATCH
          Line 1
          Line 3
          Line 4
          Line 2 MATCH
          Line 1
          Line 3
          Line 4


          The script holds the previous line in prev, printing and updating it on the non-matching lines. On lines matching the pattern, it prints the current line, leaving the previous in the variable to be printed next.



          Special cases for the first line (NR==1) when there's no previous line to print, and for the END when we print the held line.






          share|improve this answer




























            2














            If the idea is to swap the MATCH line with the immediately preceding one, then something like this would do:



            $ awk '!/MATCH/ { if (NR > 1) print prev; prev=$0} 
            /MATCH/ {print $0;}
            END {print prev}' < file
            Line 2 MATCH
            Line 1
            Line 3
            Line 4
            Line 2 MATCH
            Line 1
            Line 3
            Line 4


            The script holds the previous line in prev, printing and updating it on the non-matching lines. On lines matching the pattern, it prints the current line, leaving the previous in the variable to be printed next.



            Special cases for the first line (NR==1) when there's no previous line to print, and for the END when we print the held line.






            share|improve this answer


























              2












              2








              2







              If the idea is to swap the MATCH line with the immediately preceding one, then something like this would do:



              $ awk '!/MATCH/ { if (NR > 1) print prev; prev=$0} 
              /MATCH/ {print $0;}
              END {print prev}' < file
              Line 2 MATCH
              Line 1
              Line 3
              Line 4
              Line 2 MATCH
              Line 1
              Line 3
              Line 4


              The script holds the previous line in prev, printing and updating it on the non-matching lines. On lines matching the pattern, it prints the current line, leaving the previous in the variable to be printed next.



              Special cases for the first line (NR==1) when there's no previous line to print, and for the END when we print the held line.






              share|improve this answer













              If the idea is to swap the MATCH line with the immediately preceding one, then something like this would do:



              $ awk '!/MATCH/ { if (NR > 1) print prev; prev=$0} 
              /MATCH/ {print $0;}
              END {print prev}' < file
              Line 2 MATCH
              Line 1
              Line 3
              Line 4
              Line 2 MATCH
              Line 1
              Line 3
              Line 4


              The script holds the previous line in prev, printing and updating it on the non-matching lines. On lines matching the pattern, it prints the current line, leaving the previous in the variable to be printed next.



              Special cases for the first line (NR==1) when there's no previous line to print, and for the END when we print the held line.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Feb 17 at 21:25









              ilkkachuilkkachu

              61.9k10102178




              61.9k10102178

























                  3














                  Using ed:



                  $ printf 'g/MATCH/m-2n,pn' | ed -s file
                  Line 2 MATCH
                  Line 1
                  Line 3
                  Line 4
                  Line 2 MATCH
                  Line 1
                  Line 3
                  Line 4


                  The m command moves the current line after to the subsequent target address. Here, we find all lines matching MATCH (it's the g in front of the regular expression that makes this a "global" operation), and for each line move it one line up (to "after the line two lines up"). The effect is that the MATCH lines swap places with the immediately preceding lines.



                  The final ,p in the editing script just displays the modified editing buffer. This could be changed to something like wq to write the changed editing buffer back to the original file.



                  Note that using ed for editing files might look neat, but is not recommended for large files as the whole file is read into memory.






                  share|improve this answer






























                    3














                    Using ed:



                    $ printf 'g/MATCH/m-2n,pn' | ed -s file
                    Line 2 MATCH
                    Line 1
                    Line 3
                    Line 4
                    Line 2 MATCH
                    Line 1
                    Line 3
                    Line 4


                    The m command moves the current line after to the subsequent target address. Here, we find all lines matching MATCH (it's the g in front of the regular expression that makes this a "global" operation), and for each line move it one line up (to "after the line two lines up"). The effect is that the MATCH lines swap places with the immediately preceding lines.



                    The final ,p in the editing script just displays the modified editing buffer. This could be changed to something like wq to write the changed editing buffer back to the original file.



                    Note that using ed for editing files might look neat, but is not recommended for large files as the whole file is read into memory.






                    share|improve this answer




























                      3












                      3








                      3







                      Using ed:



                      $ printf 'g/MATCH/m-2n,pn' | ed -s file
                      Line 2 MATCH
                      Line 1
                      Line 3
                      Line 4
                      Line 2 MATCH
                      Line 1
                      Line 3
                      Line 4


                      The m command moves the current line after to the subsequent target address. Here, we find all lines matching MATCH (it's the g in front of the regular expression that makes this a "global" operation), and for each line move it one line up (to "after the line two lines up"). The effect is that the MATCH lines swap places with the immediately preceding lines.



                      The final ,p in the editing script just displays the modified editing buffer. This could be changed to something like wq to write the changed editing buffer back to the original file.



                      Note that using ed for editing files might look neat, but is not recommended for large files as the whole file is read into memory.






                      share|improve this answer















                      Using ed:



                      $ printf 'g/MATCH/m-2n,pn' | ed -s file
                      Line 2 MATCH
                      Line 1
                      Line 3
                      Line 4
                      Line 2 MATCH
                      Line 1
                      Line 3
                      Line 4


                      The m command moves the current line after to the subsequent target address. Here, we find all lines matching MATCH (it's the g in front of the regular expression that makes this a "global" operation), and for each line move it one line up (to "after the line two lines up"). The effect is that the MATCH lines swap places with the immediately preceding lines.



                      The final ,p in the editing script just displays the modified editing buffer. This could be changed to something like wq to write the changed editing buffer back to the original file.



                      Note that using ed for editing files might look neat, but is not recommended for large files as the whole file is read into memory.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Feb 18 at 7:01

























                      answered Feb 17 at 23:10









                      KusalanandaKusalananda

                      136k17257426




                      136k17257426























                          1














                          Using sed with a N;P;D cycle:



                          sed -e '$!N;s/(Line 1)(n)(.*MATCH.*)/321/;t' -e 'P;D' infile


                          This will swap only if the line with MATCH is preceded by Line 1: the t without label branches to the end of script if successful and so it avoids another swap if any Line 1 is followed by consecutive lines with MATCH. Adjust the regex for any leading/trailing blanks.






                          share|improve this answer




























                            1














                            Using sed with a N;P;D cycle:



                            sed -e '$!N;s/(Line 1)(n)(.*MATCH.*)/321/;t' -e 'P;D' infile


                            This will swap only if the line with MATCH is preceded by Line 1: the t without label branches to the end of script if successful and so it avoids another swap if any Line 1 is followed by consecutive lines with MATCH. Adjust the regex for any leading/trailing blanks.






                            share|improve this answer


























                              1












                              1








                              1







                              Using sed with a N;P;D cycle:



                              sed -e '$!N;s/(Line 1)(n)(.*MATCH.*)/321/;t' -e 'P;D' infile


                              This will swap only if the line with MATCH is preceded by Line 1: the t without label branches to the end of script if successful and so it avoids another swap if any Line 1 is followed by consecutive lines with MATCH. Adjust the regex for any leading/trailing blanks.






                              share|improve this answer













                              Using sed with a N;P;D cycle:



                              sed -e '$!N;s/(Line 1)(n)(.*MATCH.*)/321/;t' -e 'P;D' infile


                              This will swap only if the line with MATCH is preceded by Line 1: the t without label branches to the end of script if successful and so it avoids another swap if any Line 1 is followed by consecutive lines with MATCH. Adjust the regex for any leading/trailing blanks.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Feb 17 at 21:39









                              don_crisstidon_crissti

                              51.6k15141168




                              51.6k15141168























                                  1














                                  Using sed editor, we can swap two lines one of which contains Match keyword with the one preceding it.



                                   $ sed -e '
                                  /MATCH/!{
                                  x;1!p;$!d;g;q
                                  }
                                  $G
                                  ' input.txt

                                  Line 2 MATCH
                                  Line 1
                                  Line 3
                                  Line 4
                                  Line 2 MATCH
                                  Line 1
                                  Line 3
                                  Line 4





                                  share|improve this answer




























                                    1














                                    Using sed editor, we can swap two lines one of which contains Match keyword with the one preceding it.



                                     $ sed -e '
                                    /MATCH/!{
                                    x;1!p;$!d;g;q
                                    }
                                    $G
                                    ' input.txt

                                    Line 2 MATCH
                                    Line 1
                                    Line 3
                                    Line 4
                                    Line 2 MATCH
                                    Line 1
                                    Line 3
                                    Line 4





                                    share|improve this answer


























                                      1












                                      1








                                      1







                                      Using sed editor, we can swap two lines one of which contains Match keyword with the one preceding it.



                                       $ sed -e '
                                      /MATCH/!{
                                      x;1!p;$!d;g;q
                                      }
                                      $G
                                      ' input.txt

                                      Line 2 MATCH
                                      Line 1
                                      Line 3
                                      Line 4
                                      Line 2 MATCH
                                      Line 1
                                      Line 3
                                      Line 4





                                      share|improve this answer













                                      Using sed editor, we can swap two lines one of which contains Match keyword with the one preceding it.



                                       $ sed -e '
                                      /MATCH/!{
                                      x;1!p;$!d;g;q
                                      }
                                      $G
                                      ' input.txt

                                      Line 2 MATCH
                                      Line 1
                                      Line 3
                                      Line 4
                                      Line 2 MATCH
                                      Line 1
                                      Line 3
                                      Line 4






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Feb 18 at 3:42









                                      Rakesh SharmaRakesh Sharma

                                      342115




                                      342115























                                          -1














                                          sed "s/line 2 match//g"|sed "s/line 1/line 2 matchn&/g"



                                          Above command worked fine






                                          share|improve this answer



















                                          • 2





                                            The lines with MATCH should swap places with the preceding lines.

                                            – Kusalananda
                                            Feb 17 at 23:19
















                                          -1














                                          sed "s/line 2 match//g"|sed "s/line 1/line 2 matchn&/g"



                                          Above command worked fine






                                          share|improve this answer



















                                          • 2





                                            The lines with MATCH should swap places with the preceding lines.

                                            – Kusalananda
                                            Feb 17 at 23:19














                                          -1












                                          -1








                                          -1







                                          sed "s/line 2 match//g"|sed "s/line 1/line 2 matchn&/g"



                                          Above command worked fine






                                          share|improve this answer













                                          sed "s/line 2 match//g"|sed "s/line 1/line 2 matchn&/g"



                                          Above command worked fine







                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Feb 17 at 23:05









                                          Praveen Kumar BSPraveen Kumar BS

                                          1,6351311




                                          1,6351311








                                          • 2





                                            The lines with MATCH should swap places with the preceding lines.

                                            – Kusalananda
                                            Feb 17 at 23:19














                                          • 2





                                            The lines with MATCH should swap places with the preceding lines.

                                            – Kusalananda
                                            Feb 17 at 23:19








                                          2




                                          2





                                          The lines with MATCH should swap places with the preceding lines.

                                          – Kusalananda
                                          Feb 17 at 23:19





                                          The lines with MATCH should swap places with the preceding lines.

                                          – Kusalananda
                                          Feb 17 at 23:19


















                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Unix & Linux Stack Exchange!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501234%2fswap-a-line-with-another%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          Probability when a professor distributes a quiz and homework assignment to a class of n students.

                                          Aardman Animations

                                          Are they similar matrix