Find a string and replace another string after the first is found

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
1
down vote

favorite












File:



1
2
3
4
1
5
6
7
4


I would like to search for a string, in this case 1, and then change the next string of 4 to 8.

Expected output:



1
2
3
8
1
5
6
7
4


I've tried:



cat file | sed '/1/ s/4/8/'


But that only looks for a string to change in that line.

I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.

I do not have GNU sed installed.







share|improve this question


















  • 2




    if the first occurence of 4 has to be changed you don't need anything sed "/4/8/" file that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
    – francois P
    Jan 22 at 21:29






  • 2




    What if there's another 1 further down which is followed by another 4 ? Do you need to replace only the 1st 4 in the file which occurs after a 1 or do you need to repeat that for each 1st 4 that follows after a 1 ?
    – don_crissti
    Jan 22 at 21:36










  • Yes I edited the file and expected output. Sorry
    – user1712037
    Jan 22 at 21:46










  • @user1712037,how about awk solution?
    – RomanPerekhrest
    Jan 22 at 21:49










  • Sure. What would the awk syntax look like?
    – user1712037
    Jan 22 at 21:51














up vote
1
down vote

favorite












File:



1
2
3
4
1
5
6
7
4


I would like to search for a string, in this case 1, and then change the next string of 4 to 8.

Expected output:



1
2
3
8
1
5
6
7
4


I've tried:



cat file | sed '/1/ s/4/8/'


But that only looks for a string to change in that line.

I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.

I do not have GNU sed installed.







share|improve this question


















  • 2




    if the first occurence of 4 has to be changed you don't need anything sed "/4/8/" file that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
    – francois P
    Jan 22 at 21:29






  • 2




    What if there's another 1 further down which is followed by another 4 ? Do you need to replace only the 1st 4 in the file which occurs after a 1 or do you need to repeat that for each 1st 4 that follows after a 1 ?
    – don_crissti
    Jan 22 at 21:36










  • Yes I edited the file and expected output. Sorry
    – user1712037
    Jan 22 at 21:46










  • @user1712037,how about awk solution?
    – RomanPerekhrest
    Jan 22 at 21:49










  • Sure. What would the awk syntax look like?
    – user1712037
    Jan 22 at 21:51












up vote
1
down vote

favorite









up vote
1
down vote

favorite











File:



1
2
3
4
1
5
6
7
4


I would like to search for a string, in this case 1, and then change the next string of 4 to 8.

Expected output:



1
2
3
8
1
5
6
7
4


I've tried:



cat file | sed '/1/ s/4/8/'


But that only looks for a string to change in that line.

I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.

I do not have GNU sed installed.







share|improve this question














File:



1
2
3
4
1
5
6
7
4


I would like to search for a string, in this case 1, and then change the next string of 4 to 8.

Expected output:



1
2
3
8
1
5
6
7
4


I've tried:



cat file | sed '/1/ s/4/8/'


But that only looks for a string to change in that line.

I also can't use line number to replace in my original file because there might be a different number of lines between the first string and the second.

I do not have GNU sed installed.









share|improve this question













share|improve this question




share|improve this question








edited Jan 22 at 21:46

























asked Jan 22 at 21:20









user1712037

53117




53117







  • 2




    if the first occurence of 4 has to be changed you don't need anything sed "/4/8/" file that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
    – francois P
    Jan 22 at 21:29






  • 2




    What if there's another 1 further down which is followed by another 4 ? Do you need to replace only the 1st 4 in the file which occurs after a 1 or do you need to repeat that for each 1st 4 that follows after a 1 ?
    – don_crissti
    Jan 22 at 21:36










  • Yes I edited the file and expected output. Sorry
    – user1712037
    Jan 22 at 21:46










  • @user1712037,how about awk solution?
    – RomanPerekhrest
    Jan 22 at 21:49










  • Sure. What would the awk syntax look like?
    – user1712037
    Jan 22 at 21:51












  • 2




    if the first occurence of 4 has to be changed you don't need anything sed "/4/8/" file that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
    – francois P
    Jan 22 at 21:29






  • 2




    What if there's another 1 further down which is followed by another 4 ? Do you need to replace only the 1st 4 in the file which occurs after a 1 or do you need to repeat that for each 1st 4 that follows after a 1 ?
    – don_crissti
    Jan 22 at 21:36










  • Yes I edited the file and expected output. Sorry
    – user1712037
    Jan 22 at 21:46










  • @user1712037,how about awk solution?
    – RomanPerekhrest
    Jan 22 at 21:49










  • Sure. What would the awk syntax look like?
    – user1712037
    Jan 22 at 21:51







2




2




if the first occurence of 4 has to be changed you don't need anything sed "/4/8/" file that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
– francois P
Jan 22 at 21:29




if the first occurence of 4 has to be changed you don't need anything sed "/4/8/" file that's all /foo/ s/bar/foo/ means on line with foo .... substitute....
– francois P
Jan 22 at 21:29




2




2




What if there's another 1 further down which is followed by another 4 ? Do you need to replace only the 1st 4 in the file which occurs after a 1 or do you need to repeat that for each 1st 4 that follows after a 1 ?
– don_crissti
Jan 22 at 21:36




What if there's another 1 further down which is followed by another 4 ? Do you need to replace only the 1st 4 in the file which occurs after a 1 or do you need to repeat that for each 1st 4 that follows after a 1 ?
– don_crissti
Jan 22 at 21:36












Yes I edited the file and expected output. Sorry
– user1712037
Jan 22 at 21:46




Yes I edited the file and expected output. Sorry
– user1712037
Jan 22 at 21:46












@user1712037,how about awk solution?
– RomanPerekhrest
Jan 22 at 21:49




@user1712037,how about awk solution?
– RomanPerekhrest
Jan 22 at 21:49












Sure. What would the awk syntax look like?
– user1712037
Jan 22 at 21:51




Sure. What would the awk syntax look like?
– user1712037
Jan 22 at 21:51










5 Answers
5






active

oldest

votes

















up vote
2
down vote



accepted










The POSIX-specified file editor, ex, is capable of doing exactly that.



printf '%sn' '/1//4/s//8/' x | ex file.txt


ex is capable of combining multiple addresses. So /1/ means "Go to" (or refer to) "the next line matching regex 1." Then /4/ goes from that line to the next line matching 4. And s//8/ has the usual meaning; as in Sed, a blank regex passed to the s command means "reuse last regex used" which in this case is 4.



To print the modified file but not save the changes, use the following command instead:



printf '%sn' '/1//4/s//8/' %p | ex file.txt


Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry before the first line containing banana after line 27:



printf '%sn' '27/banana/?cherry?d' x | ex file.txt


x means to save changes and exit, and %p means "print whole file." (% is a synonym for 1,$, which is an address range from the first line to the last line.)






share|improve this answer



























    up vote
    1
    down vote













    To replace only the 1st PATTERN that occurs after a MARKER you could do:



    sed '/MARKER/,$
    /PATTERN/
    x
    //
    x
    b

    g
    s/PATTERN/REPLACEMENT/

    ' infile


    Use a range (from the 1st MARKER to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.






    share|improve this answer





























      up vote
      1
      down vote













      generic solution using awk, consider the following modified input file with multiple 1s and 4s



      $ cat ip.txt
      1
      foo
      1
      xyz
      4
      4
      1
      1
      eeeee
      4
      1
      rrrrrr
      4
      1
      4


      Use a flag to indicate that 1 was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again



      $ # first block
      $ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
      1
      foo
      1
      xyz
      8
      4
      1
      1
      eeeee
      4
      1
      rrrrrr
      4
      1
      4

      $ # second block
      $ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
      1
      foo
      1
      xyz
      4
      4
      1
      1
      eeeee
      8
      1
      rrrrrr
      4
      1
      4


      can be simplified for changing only first block



      awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt





      share|improve this answer



























        up vote
        0
        down vote













        Awk solution:



        awk '$1==1 f++ f==1 && $1==4 $1=8 1' file


        The output:



        1
        2
        3
        8
        1
        5
        6
        7
        4





        share|improve this answer




















        • awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
          – user1712037
          Jan 22 at 22:28










        • @user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
          – RomanPerekhrest
          Jan 22 at 22:31







        • 1




          This won't work if there are multiple lines matching 1 before the 1st 4 that follows...
          – don_crissti
          Jan 22 at 23:07










        • @don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
          – RomanPerekhrest
          Jan 23 at 8:25

















        up vote
        0
        down vote













        With awk it is more easy and compatible to any Nth occurrence needed



        awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME


        example :



        -bash-4.4$ cat toto
        1
        2
        3
        4
        5
        6
        1
        2
        3
        4
        5
        6
        1
        2
        3
        4
        -bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
        1
        2
        3
        4
        5
        6
        1
        2
        3
        ---8
        5
        6
        1
        2
        3
        4
        -bash-4.4$


        only the second 4 is changed but not the first or the last.






        share|improve this answer


















        • 1




          but this is not even checking if 1 occurred first...
          – Sundeep
          Jan 23 at 4:10










        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',
        convertImagesToLinks: false,
        noModals: false,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        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%2f418946%2ffind-a-string-and-replace-another-string-after-the-first-is-found%23new-answer', 'question_page');

        );

        Post as a guest






























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        2
        down vote



        accepted










        The POSIX-specified file editor, ex, is capable of doing exactly that.



        printf '%sn' '/1//4/s//8/' x | ex file.txt


        ex is capable of combining multiple addresses. So /1/ means "Go to" (or refer to) "the next line matching regex 1." Then /4/ goes from that line to the next line matching 4. And s//8/ has the usual meaning; as in Sed, a blank regex passed to the s command means "reuse last regex used" which in this case is 4.



        To print the modified file but not save the changes, use the following command instead:



        printf '%sn' '/1//4/s//8/' %p | ex file.txt


        Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry before the first line containing banana after line 27:



        printf '%sn' '27/banana/?cherry?d' x | ex file.txt


        x means to save changes and exit, and %p means "print whole file." (% is a synonym for 1,$, which is an address range from the first line to the last line.)






        share|improve this answer
























          up vote
          2
          down vote



          accepted










          The POSIX-specified file editor, ex, is capable of doing exactly that.



          printf '%sn' '/1//4/s//8/' x | ex file.txt


          ex is capable of combining multiple addresses. So /1/ means "Go to" (or refer to) "the next line matching regex 1." Then /4/ goes from that line to the next line matching 4. And s//8/ has the usual meaning; as in Sed, a blank regex passed to the s command means "reuse last regex used" which in this case is 4.



          To print the modified file but not save the changes, use the following command instead:



          printf '%sn' '/1//4/s//8/' %p | ex file.txt


          Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry before the first line containing banana after line 27:



          printf '%sn' '27/banana/?cherry?d' x | ex file.txt


          x means to save changes and exit, and %p means "print whole file." (% is a synonym for 1,$, which is an address range from the first line to the last line.)






          share|improve this answer






















            up vote
            2
            down vote



            accepted







            up vote
            2
            down vote



            accepted






            The POSIX-specified file editor, ex, is capable of doing exactly that.



            printf '%sn' '/1//4/s//8/' x | ex file.txt


            ex is capable of combining multiple addresses. So /1/ means "Go to" (or refer to) "the next line matching regex 1." Then /4/ goes from that line to the next line matching 4. And s//8/ has the usual meaning; as in Sed, a blank regex passed to the s command means "reuse last regex used" which in this case is 4.



            To print the modified file but not save the changes, use the following command instead:



            printf '%sn' '/1//4/s//8/' %p | ex file.txt


            Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry before the first line containing banana after line 27:



            printf '%sn' '27/banana/?cherry?d' x | ex file.txt


            x means to save changes and exit, and %p means "print whole file." (% is a synonym for 1,$, which is an address range from the first line to the last line.)






            share|improve this answer












            The POSIX-specified file editor, ex, is capable of doing exactly that.



            printf '%sn' '/1//4/s//8/' x | ex file.txt


            ex is capable of combining multiple addresses. So /1/ means "Go to" (or refer to) "the next line matching regex 1." Then /4/ goes from that line to the next line matching 4. And s//8/ has the usual meaning; as in Sed, a blank regex passed to the s command means "reuse last regex used" which in this case is 4.



            To print the modified file but not save the changes, use the following command instead:



            printf '%sn' '/1//4/s//8/' %p | ex file.txt


            Just to give the idea of multiple addresses better, the following command deletes the first line containing cherry before the first line containing banana after line 27:



            printf '%sn' '27/banana/?cherry?d' x | ex file.txt


            x means to save changes and exit, and %p means "print whole file." (% is a synonym for 1,$, which is an address range from the first line to the last line.)







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 22 at 22:42









            Wildcard

            22k855154




            22k855154






















                up vote
                1
                down vote













                To replace only the 1st PATTERN that occurs after a MARKER you could do:



                sed '/MARKER/,$
                /PATTERN/
                x
                //
                x
                b

                g
                s/PATTERN/REPLACEMENT/

                ' infile


                Use a range (from the 1st MARKER to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.






                share|improve this answer


























                  up vote
                  1
                  down vote













                  To replace only the 1st PATTERN that occurs after a MARKER you could do:



                  sed '/MARKER/,$
                  /PATTERN/
                  x
                  //
                  x
                  b

                  g
                  s/PATTERN/REPLACEMENT/

                  ' infile


                  Use a range (from the 1st MARKER to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.






                  share|improve this answer
























                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    To replace only the 1st PATTERN that occurs after a MARKER you could do:



                    sed '/MARKER/,$
                    /PATTERN/
                    x
                    //
                    x
                    b

                    g
                    s/PATTERN/REPLACEMENT/

                    ' infile


                    Use a range (from the 1st MARKER to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.






                    share|improve this answer














                    To replace only the 1st PATTERN that occurs after a MARKER you could do:



                    sed '/MARKER/,$
                    /PATTERN/
                    x
                    //
                    x
                    b

                    g
                    s/PATTERN/REPLACEMENT/

                    ' infile


                    Use a range (from the 1st MARKER to the end of file) and the hold buffer. Each time you encounter a line matching PATTERN you exchange buffers and check if the line that was in hold space matches too: if it does, then exchange back and go to end of script; else overwrite with current line and replace.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 22 at 22:56

























                    answered Jan 22 at 22:40









                    don_crissti

                    46.6k15124153




                    46.6k15124153




















                        up vote
                        1
                        down vote













                        generic solution using awk, consider the following modified input file with multiple 1s and 4s



                        $ cat ip.txt
                        1
                        foo
                        1
                        xyz
                        4
                        4
                        1
                        1
                        eeeee
                        4
                        1
                        rrrrrr
                        4
                        1
                        4


                        Use a flag to indicate that 1 was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again



                        $ # first block
                        $ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
                        1
                        foo
                        1
                        xyz
                        8
                        4
                        1
                        1
                        eeeee
                        4
                        1
                        rrrrrr
                        4
                        1
                        4

                        $ # second block
                        $ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
                        1
                        foo
                        1
                        xyz
                        4
                        4
                        1
                        1
                        eeeee
                        8
                        1
                        rrrrrr
                        4
                        1
                        4


                        can be simplified for changing only first block



                        awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt





                        share|improve this answer
























                          up vote
                          1
                          down vote













                          generic solution using awk, consider the following modified input file with multiple 1s and 4s



                          $ cat ip.txt
                          1
                          foo
                          1
                          xyz
                          4
                          4
                          1
                          1
                          eeeee
                          4
                          1
                          rrrrrr
                          4
                          1
                          4


                          Use a flag to indicate that 1 was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again



                          $ # first block
                          $ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
                          1
                          foo
                          1
                          xyz
                          8
                          4
                          1
                          1
                          eeeee
                          4
                          1
                          rrrrrr
                          4
                          1
                          4

                          $ # second block
                          $ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
                          1
                          foo
                          1
                          xyz
                          4
                          4
                          1
                          1
                          eeeee
                          8
                          1
                          rrrrrr
                          4
                          1
                          4


                          can be simplified for changing only first block



                          awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt





                          share|improve this answer






















                            up vote
                            1
                            down vote










                            up vote
                            1
                            down vote









                            generic solution using awk, consider the following modified input file with multiple 1s and 4s



                            $ cat ip.txt
                            1
                            foo
                            1
                            xyz
                            4
                            4
                            1
                            1
                            eeeee
                            4
                            1
                            rrrrrr
                            4
                            1
                            4


                            Use a flag to indicate that 1 was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again



                            $ # first block
                            $ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
                            1
                            foo
                            1
                            xyz
                            8
                            4
                            1
                            1
                            eeeee
                            4
                            1
                            rrrrrr
                            4
                            1
                            4

                            $ # second block
                            $ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
                            1
                            foo
                            1
                            xyz
                            4
                            4
                            1
                            1
                            eeeee
                            8
                            1
                            rrrrrr
                            4
                            1
                            4


                            can be simplified for changing only first block



                            awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt





                            share|improve this answer












                            generic solution using awk, consider the following modified input file with multiple 1s and 4s



                            $ cat ip.txt
                            1
                            foo
                            1
                            xyz
                            4
                            4
                            1
                            1
                            eeeee
                            4
                            1
                            rrrrrr
                            4
                            1
                            4


                            Use a flag to indicate that 1 was matched and a counter to know which block is being modified. Clearing the flag is needed to start the matching cycle again



                            $ # first block
                            $ awk '/1/f=1 f && /4/c++; f=0; if(c==1) $0="8" 1' ip.txt
                            1
                            foo
                            1
                            xyz
                            8
                            4
                            1
                            1
                            eeeee
                            4
                            1
                            rrrrrr
                            4
                            1
                            4

                            $ # second block
                            $ awk '/1/f=1 f && /4/c++; f=0; if(c==2) $0="8" 1' ip.txt
                            1
                            foo
                            1
                            xyz
                            4
                            4
                            1
                            1
                            eeeee
                            8
                            1
                            rrrrrr
                            4
                            1
                            4


                            can be simplified for changing only first block



                            awk '/1/f=1 f && !c && /4/c++; $0="8" 1' ip.txt






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Jan 23 at 4:18









                            Sundeep

                            6,9511826




                            6,9511826




















                                up vote
                                0
                                down vote













                                Awk solution:



                                awk '$1==1 f++ f==1 && $1==4 $1=8 1' file


                                The output:



                                1
                                2
                                3
                                8
                                1
                                5
                                6
                                7
                                4





                                share|improve this answer




















                                • awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
                                  – user1712037
                                  Jan 22 at 22:28










                                • @user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
                                  – RomanPerekhrest
                                  Jan 22 at 22:31







                                • 1




                                  This won't work if there are multiple lines matching 1 before the 1st 4 that follows...
                                  – don_crissti
                                  Jan 22 at 23:07










                                • @don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
                                  – RomanPerekhrest
                                  Jan 23 at 8:25














                                up vote
                                0
                                down vote













                                Awk solution:



                                awk '$1==1 f++ f==1 && $1==4 $1=8 1' file


                                The output:



                                1
                                2
                                3
                                8
                                1
                                5
                                6
                                7
                                4





                                share|improve this answer




















                                • awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
                                  – user1712037
                                  Jan 22 at 22:28










                                • @user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
                                  – RomanPerekhrest
                                  Jan 22 at 22:31







                                • 1




                                  This won't work if there are multiple lines matching 1 before the 1st 4 that follows...
                                  – don_crissti
                                  Jan 22 at 23:07










                                • @don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
                                  – RomanPerekhrest
                                  Jan 23 at 8:25












                                up vote
                                0
                                down vote










                                up vote
                                0
                                down vote









                                Awk solution:



                                awk '$1==1 f++ f==1 && $1==4 $1=8 1' file


                                The output:



                                1
                                2
                                3
                                8
                                1
                                5
                                6
                                7
                                4





                                share|improve this answer












                                Awk solution:



                                awk '$1==1 f++ f==1 && $1==4 $1=8 1' file


                                The output:



                                1
                                2
                                3
                                8
                                1
                                5
                                6
                                7
                                4






                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Jan 22 at 21:58









                                RomanPerekhrest

                                22.4k12144




                                22.4k12144











                                • awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
                                  – user1712037
                                  Jan 22 at 22:28










                                • @user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
                                  – RomanPerekhrest
                                  Jan 22 at 22:31







                                • 1




                                  This won't work if there are multiple lines matching 1 before the 1st 4 that follows...
                                  – don_crissti
                                  Jan 22 at 23:07










                                • @don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
                                  – RomanPerekhrest
                                  Jan 23 at 8:25
















                                • awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
                                  – user1712037
                                  Jan 22 at 22:28










                                • @user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
                                  – RomanPerekhrest
                                  Jan 22 at 22:31







                                • 1




                                  This won't work if there are multiple lines matching 1 before the 1st 4 that follows...
                                  – don_crissti
                                  Jan 22 at 23:07










                                • @don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
                                  – RomanPerekhrest
                                  Jan 23 at 8:25















                                awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
                                – user1712037
                                Jan 22 at 22:28




                                awk '$1==1 f++ f==1 && $1==4 $1=8 1' num.txt awk: syntax error near line 1 awk: bailing out near line 1
                                – user1712037
                                Jan 22 at 22:28












                                @user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
                                – RomanPerekhrest
                                Jan 22 at 22:31





                                @user1712037, it can not be so. Check if you run this command as standalone, not as part of some pipeline or else. Or ... you are not on Linux system
                                – RomanPerekhrest
                                Jan 22 at 22:31





                                1




                                1




                                This won't work if there are multiple lines matching 1 before the 1st 4 that follows...
                                – don_crissti
                                Jan 22 at 23:07




                                This won't work if there are multiple lines matching 1 before the 1st 4 that follows...
                                – don_crissti
                                Jan 22 at 23:07












                                @don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
                                – RomanPerekhrest
                                Jan 23 at 8:25




                                @don_crissti, I don't see such input sample - share some link to the text fragment you mentioned
                                – RomanPerekhrest
                                Jan 23 at 8:25










                                up vote
                                0
                                down vote













                                With awk it is more easy and compatible to any Nth occurrence needed



                                awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME


                                example :



                                -bash-4.4$ cat toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                ---8
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$


                                only the second 4 is changed but not the first or the last.






                                share|improve this answer


















                                • 1




                                  but this is not even checking if 1 occurred first...
                                  – Sundeep
                                  Jan 23 at 4:10














                                up vote
                                0
                                down vote













                                With awk it is more easy and compatible to any Nth occurrence needed



                                awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME


                                example :



                                -bash-4.4$ cat toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                ---8
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$


                                only the second 4 is changed but not the first or the last.






                                share|improve this answer


















                                • 1




                                  but this is not even checking if 1 occurred first...
                                  – Sundeep
                                  Jan 23 at 4:10












                                up vote
                                0
                                down vote










                                up vote
                                0
                                down vote









                                With awk it is more easy and compatible to any Nth occurrence needed



                                awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME


                                example :



                                -bash-4.4$ cat toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                ---8
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$


                                only the second 4 is changed but not the first or the last.






                                share|improve this answer














                                With awk it is more easy and compatible to any Nth occurrence needed



                                awk '/pattern to search/n+=1if (n==OCCURRENCE)sub("PATTERN","SUBSTITUTE",$0);print ' FILE-NAME


                                example :



                                -bash-4.4$ cat toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$ awk '/4/n+=1if (n==2)sub("4","---8",$0);print ' toto
                                1
                                2
                                3
                                4
                                5
                                6
                                1
                                2
                                3
                                ---8
                                5
                                6
                                1
                                2
                                3
                                4
                                -bash-4.4$


                                only the second 4 is changed but not the first or the last.







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Jan 22 at 22:16









                                ilkkachu

                                49.8k674137




                                49.8k674137










                                answered Jan 22 at 22:07









                                francois P

                                914114




                                914114







                                • 1




                                  but this is not even checking if 1 occurred first...
                                  – Sundeep
                                  Jan 23 at 4:10












                                • 1




                                  but this is not even checking if 1 occurred first...
                                  – Sundeep
                                  Jan 23 at 4:10







                                1




                                1




                                but this is not even checking if 1 occurred first...
                                – Sundeep
                                Jan 23 at 4:10




                                but this is not even checking if 1 occurred first...
                                – Sundeep
                                Jan 23 at 4:10












                                 

                                draft saved


                                draft discarded


























                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f418946%2ffind-a-string-and-replace-another-string-after-the-first-is-found%23new-answer', 'question_page');

                                );

                                Post as a guest













































































                                Popular posts from this blog

                                How to check contact read email or not when send email to Individual?

                                Displaying single band from multi-band raster using QGIS

                                How many registers does an x86_64 CPU actually have?