substitute with SED recursively

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











up vote
3
down vote

favorite












Is it possible to substitute a sample recursively in multi directory with grep and sed like that ?



grep -e "http://localhost:4000" -r ~/dev_web/_site | sed -e 's/http://localhost:4000/https://another_site.com/g'


When I do that, my terminal show me that is done, but when I do again a grep:



grep -e "https://another_site.com" -r ~/dev_web/_site


it show me only 4 files changed..



And if I do :



 grep -e "http://localhost:4000" -r ~/dev_web/_site/


the sample http:localhost:4000 is still here







share|improve this question

























    up vote
    3
    down vote

    favorite












    Is it possible to substitute a sample recursively in multi directory with grep and sed like that ?



    grep -e "http://localhost:4000" -r ~/dev_web/_site | sed -e 's/http://localhost:4000/https://another_site.com/g'


    When I do that, my terminal show me that is done, but when I do again a grep:



    grep -e "https://another_site.com" -r ~/dev_web/_site


    it show me only 4 files changed..



    And if I do :



     grep -e "http://localhost:4000" -r ~/dev_web/_site/


    the sample http:localhost:4000 is still here







    share|improve this question























      up vote
      3
      down vote

      favorite









      up vote
      3
      down vote

      favorite











      Is it possible to substitute a sample recursively in multi directory with grep and sed like that ?



      grep -e "http://localhost:4000" -r ~/dev_web/_site | sed -e 's/http://localhost:4000/https://another_site.com/g'


      When I do that, my terminal show me that is done, but when I do again a grep:



      grep -e "https://another_site.com" -r ~/dev_web/_site


      it show me only 4 files changed..



      And if I do :



       grep -e "http://localhost:4000" -r ~/dev_web/_site/


      the sample http:localhost:4000 is still here







      share|improve this question













      Is it possible to substitute a sample recursively in multi directory with grep and sed like that ?



      grep -e "http://localhost:4000" -r ~/dev_web/_site | sed -e 's/http://localhost:4000/https://another_site.com/g'


      When I do that, my terminal show me that is done, but when I do again a grep:



      grep -e "https://another_site.com" -r ~/dev_web/_site


      it show me only 4 files changed..



      And if I do :



       grep -e "http://localhost:4000" -r ~/dev_web/_site/


      the sample http:localhost:4000 is still here









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jul 4 at 13:03









      Jeff Schaller

      30.8k846104




      30.8k846104









      asked Jul 4 at 12:16









      ordinatous

      213




      213




















          3 Answers
          3






          active

          oldest

          votes

















          up vote
          3
          down vote













          Your pipeline changes no files. It pulls out lines that matches the regular expression using grep, then changes that data, but does not attempt to make changes in any files.



          Instead, assuming GNU sed:



          find ~/dev_web/_site -type f 
          -exec grep -qF 'http://localhost:4000' ';'
          -exec sed -i 's#http://localhost:4000#https://another.site#g' +


          This would find all regular files in or under the directory ~/dev_web/_site. For each such file, grep first tests whether the file contains the given string. If it does, GNU sed is invoked to make an in-place substitution.



          The grep step could be omitted, but GNU sed would update the modification timestamp on all files without it.



          You may want to only look in a subset of the files in the directories beneath ~/dev_web/_site. If this is the case, restrict the search with something like -name '*.js' (or whatever name pattern you want to match) just after -type f.



          Adding -print just before -exec sed ... would print the pathnames of the files that find would give to sed.



          Related:



          • Understanding the -exec option of `find`





          share|improve this answer






























            up vote
            1
            down vote













            your sed session worked on grep's output, not actual file.



            use grep to list file (*)



            grep -e "http://localhost:4000" -r ~/dev_web/_site -l 


            then use xargs and sed -i to edit in place



            xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


            (on a side note you can change delimiter in sed)



            Now all together



            grep -e "http://localhost:4000" -r ~/dev_web/_site -l |
            xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


            This can be one-lined of course, note that pipe symbol (|) can be use a line continuation.



            (*) I assume file don't have space, new line and other funny char in their names.






            share|improve this answer






























              up vote
              1
              down vote













              Your first grep extract lines from files, not list files.

              To obtain a list of files matched use the -l option to grep:



              $ grep -rl "htt...." ~/dir


              To execute the modification of files with sed, give the list to sed (invert the order):



              $ sed -e 's#http://localhost:4000#https://another_site.com#g' 
              $(grep -rle "http://localhost:4000" ~/dev_web/_site)


              That assume "clean" filenames: No spaces or new lines.



              A more robust option is to use find:



              fromname='http://localhost:4000
              toname='https://another_site.com'
              searchdir=~/dev_web/_site
              find "$searchdir" -type f
              -exec grep -qF "$fromname" ';'
              -exec sed -i 's#'"$fromname"'#'"$toname"'#g' +





              share|improve this answer





















                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%2f453416%2fsubstitute-with-sed-recursively%23new-answer', 'question_page');

                );

                Post as a guest






























                3 Answers
                3






                active

                oldest

                votes








                3 Answers
                3






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                3
                down vote













                Your pipeline changes no files. It pulls out lines that matches the regular expression using grep, then changes that data, but does not attempt to make changes in any files.



                Instead, assuming GNU sed:



                find ~/dev_web/_site -type f 
                -exec grep -qF 'http://localhost:4000' ';'
                -exec sed -i 's#http://localhost:4000#https://another.site#g' +


                This would find all regular files in or under the directory ~/dev_web/_site. For each such file, grep first tests whether the file contains the given string. If it does, GNU sed is invoked to make an in-place substitution.



                The grep step could be omitted, but GNU sed would update the modification timestamp on all files without it.



                You may want to only look in a subset of the files in the directories beneath ~/dev_web/_site. If this is the case, restrict the search with something like -name '*.js' (or whatever name pattern you want to match) just after -type f.



                Adding -print just before -exec sed ... would print the pathnames of the files that find would give to sed.



                Related:



                • Understanding the -exec option of `find`





                share|improve this answer



























                  up vote
                  3
                  down vote













                  Your pipeline changes no files. It pulls out lines that matches the regular expression using grep, then changes that data, but does not attempt to make changes in any files.



                  Instead, assuming GNU sed:



                  find ~/dev_web/_site -type f 
                  -exec grep -qF 'http://localhost:4000' ';'
                  -exec sed -i 's#http://localhost:4000#https://another.site#g' +


                  This would find all regular files in or under the directory ~/dev_web/_site. For each such file, grep first tests whether the file contains the given string. If it does, GNU sed is invoked to make an in-place substitution.



                  The grep step could be omitted, but GNU sed would update the modification timestamp on all files without it.



                  You may want to only look in a subset of the files in the directories beneath ~/dev_web/_site. If this is the case, restrict the search with something like -name '*.js' (or whatever name pattern you want to match) just after -type f.



                  Adding -print just before -exec sed ... would print the pathnames of the files that find would give to sed.



                  Related:



                  • Understanding the -exec option of `find`





                  share|improve this answer

























                    up vote
                    3
                    down vote










                    up vote
                    3
                    down vote









                    Your pipeline changes no files. It pulls out lines that matches the regular expression using grep, then changes that data, but does not attempt to make changes in any files.



                    Instead, assuming GNU sed:



                    find ~/dev_web/_site -type f 
                    -exec grep -qF 'http://localhost:4000' ';'
                    -exec sed -i 's#http://localhost:4000#https://another.site#g' +


                    This would find all regular files in or under the directory ~/dev_web/_site. For each such file, grep first tests whether the file contains the given string. If it does, GNU sed is invoked to make an in-place substitution.



                    The grep step could be omitted, but GNU sed would update the modification timestamp on all files without it.



                    You may want to only look in a subset of the files in the directories beneath ~/dev_web/_site. If this is the case, restrict the search with something like -name '*.js' (or whatever name pattern you want to match) just after -type f.



                    Adding -print just before -exec sed ... would print the pathnames of the files that find would give to sed.



                    Related:



                    • Understanding the -exec option of `find`





                    share|improve this answer















                    Your pipeline changes no files. It pulls out lines that matches the regular expression using grep, then changes that data, but does not attempt to make changes in any files.



                    Instead, assuming GNU sed:



                    find ~/dev_web/_site -type f 
                    -exec grep -qF 'http://localhost:4000' ';'
                    -exec sed -i 's#http://localhost:4000#https://another.site#g' +


                    This would find all regular files in or under the directory ~/dev_web/_site. For each such file, grep first tests whether the file contains the given string. If it does, GNU sed is invoked to make an in-place substitution.



                    The grep step could be omitted, but GNU sed would update the modification timestamp on all files without it.



                    You may want to only look in a subset of the files in the directories beneath ~/dev_web/_site. If this is the case, restrict the search with something like -name '*.js' (or whatever name pattern you want to match) just after -type f.



                    Adding -print just before -exec sed ... would print the pathnames of the files that find would give to sed.



                    Related:



                    • Understanding the -exec option of `find`






                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Jul 19 at 7:33


























                    answered Jul 4 at 12:30









                    Kusalananda

                    101k13199312




                    101k13199312






















                        up vote
                        1
                        down vote













                        your sed session worked on grep's output, not actual file.



                        use grep to list file (*)



                        grep -e "http://localhost:4000" -r ~/dev_web/_site -l 


                        then use xargs and sed -i to edit in place



                        xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                        (on a side note you can change delimiter in sed)



                        Now all together



                        grep -e "http://localhost:4000" -r ~/dev_web/_site -l |
                        xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                        This can be one-lined of course, note that pipe symbol (|) can be use a line continuation.



                        (*) I assume file don't have space, new line and other funny char in their names.






                        share|improve this answer



























                          up vote
                          1
                          down vote













                          your sed session worked on grep's output, not actual file.



                          use grep to list file (*)



                          grep -e "http://localhost:4000" -r ~/dev_web/_site -l 


                          then use xargs and sed -i to edit in place



                          xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                          (on a side note you can change delimiter in sed)



                          Now all together



                          grep -e "http://localhost:4000" -r ~/dev_web/_site -l |
                          xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                          This can be one-lined of course, note that pipe symbol (|) can be use a line continuation.



                          (*) I assume file don't have space, new line and other funny char in their names.






                          share|improve this answer

























                            up vote
                            1
                            down vote










                            up vote
                            1
                            down vote









                            your sed session worked on grep's output, not actual file.



                            use grep to list file (*)



                            grep -e "http://localhost:4000" -r ~/dev_web/_site -l 


                            then use xargs and sed -i to edit in place



                            xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                            (on a side note you can change delimiter in sed)



                            Now all together



                            grep -e "http://localhost:4000" -r ~/dev_web/_site -l |
                            xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                            This can be one-lined of course, note that pipe symbol (|) can be use a line continuation.



                            (*) I assume file don't have space, new line and other funny char in their names.






                            share|improve this answer















                            your sed session worked on grep's output, not actual file.



                            use grep to list file (*)



                            grep -e "http://localhost:4000" -r ~/dev_web/_site -l 


                            then use xargs and sed -i to edit in place



                            xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                            (on a side note you can change delimiter in sed)



                            Now all together



                            grep -e "http://localhost:4000" -r ~/dev_web/_site -l |
                            xargs sed -i -e 's;http://localhost:4000;https://another_site.com;g'


                            This can be one-lined of course, note that pipe symbol (|) can be use a line continuation.



                            (*) I assume file don't have space, new line and other funny char in their names.







                            share|improve this answer















                            share|improve this answer



                            share|improve this answer








                            edited Jul 4 at 12:33


























                            answered Jul 4 at 12:27









                            Archemar

                            18.9k93365




                            18.9k93365




















                                up vote
                                1
                                down vote













                                Your first grep extract lines from files, not list files.

                                To obtain a list of files matched use the -l option to grep:



                                $ grep -rl "htt...." ~/dir


                                To execute the modification of files with sed, give the list to sed (invert the order):



                                $ sed -e 's#http://localhost:4000#https://another_site.com#g' 
                                $(grep -rle "http://localhost:4000" ~/dev_web/_site)


                                That assume "clean" filenames: No spaces or new lines.



                                A more robust option is to use find:



                                fromname='http://localhost:4000
                                toname='https://another_site.com'
                                searchdir=~/dev_web/_site
                                find "$searchdir" -type f
                                -exec grep -qF "$fromname" ';'
                                -exec sed -i 's#'"$fromname"'#'"$toname"'#g' +





                                share|improve this answer

























                                  up vote
                                  1
                                  down vote













                                  Your first grep extract lines from files, not list files.

                                  To obtain a list of files matched use the -l option to grep:



                                  $ grep -rl "htt...." ~/dir


                                  To execute the modification of files with sed, give the list to sed (invert the order):



                                  $ sed -e 's#http://localhost:4000#https://another_site.com#g' 
                                  $(grep -rle "http://localhost:4000" ~/dev_web/_site)


                                  That assume "clean" filenames: No spaces or new lines.



                                  A more robust option is to use find:



                                  fromname='http://localhost:4000
                                  toname='https://another_site.com'
                                  searchdir=~/dev_web/_site
                                  find "$searchdir" -type f
                                  -exec grep -qF "$fromname" ';'
                                  -exec sed -i 's#'"$fromname"'#'"$toname"'#g' +





                                  share|improve this answer























                                    up vote
                                    1
                                    down vote










                                    up vote
                                    1
                                    down vote









                                    Your first grep extract lines from files, not list files.

                                    To obtain a list of files matched use the -l option to grep:



                                    $ grep -rl "htt...." ~/dir


                                    To execute the modification of files with sed, give the list to sed (invert the order):



                                    $ sed -e 's#http://localhost:4000#https://another_site.com#g' 
                                    $(grep -rle "http://localhost:4000" ~/dev_web/_site)


                                    That assume "clean" filenames: No spaces or new lines.



                                    A more robust option is to use find:



                                    fromname='http://localhost:4000
                                    toname='https://another_site.com'
                                    searchdir=~/dev_web/_site
                                    find "$searchdir" -type f
                                    -exec grep -qF "$fromname" ';'
                                    -exec sed -i 's#'"$fromname"'#'"$toname"'#g' +





                                    share|improve this answer













                                    Your first grep extract lines from files, not list files.

                                    To obtain a list of files matched use the -l option to grep:



                                    $ grep -rl "htt...." ~/dir


                                    To execute the modification of files with sed, give the list to sed (invert the order):



                                    $ sed -e 's#http://localhost:4000#https://another_site.com#g' 
                                    $(grep -rle "http://localhost:4000" ~/dev_web/_site)


                                    That assume "clean" filenames: No spaces or new lines.



                                    A more robust option is to use find:



                                    fromname='http://localhost:4000
                                    toname='https://another_site.com'
                                    searchdir=~/dev_web/_site
                                    find "$searchdir" -type f
                                    -exec grep -qF "$fromname" ';'
                                    -exec sed -i 's#'"$fromname"'#'"$toname"'#g' +






                                    share|improve this answer













                                    share|improve this answer



                                    share|improve this answer











                                    answered Jul 4 at 16:59









                                    Isaac

                                    6,2331632




                                    6,2331632






















                                         

                                        draft saved


                                        draft discarded


























                                         


                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f453416%2fsubstitute-with-sed-recursively%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?

                                        Bahrain

                                        Postfix configuration issue with fips on centos 7; mailgun relay