Using sed to replace a string with special chars with another string with special characters












1















I'm trying to automate switching out a bash prompt for another in .bashrc



Original String:



PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '


Replacement Strings:



IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '


One of many poor attempts at writing bash to do so:



#!/bin/bash
original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '"
replacement="PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '"
ipvar="IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )"

cp ~/.bashrc ~/.bashrc.bak
sed -e 's/$original/$replacement/g' ~/.bashrc


I've tried double escaping all of the characters because I know sed needs '','/', and '&' escaped. I just can't seem to wrap my head around this one.



I didn't even bother trying to get the IP line in there right away because I couldn't replace the first line.



If there are any better methods for this type of automation please let me know.










share|improve this question





























    1















    I'm trying to automate switching out a bash prompt for another in .bashrc



    Original String:



    PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '


    Replacement Strings:



    IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
    PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '


    One of many poor attempts at writing bash to do so:



    #!/bin/bash
    original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '"
    replacement="PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '"
    ipvar="IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )"

    cp ~/.bashrc ~/.bashrc.bak
    sed -e 's/$original/$replacement/g' ~/.bashrc


    I've tried double escaping all of the characters because I know sed needs '','/', and '&' escaped. I just can't seem to wrap my head around this one.



    I didn't even bother trying to get the IP line in there right away because I couldn't replace the first line.



    If there are any better methods for this type of automation please let me know.










    share|improve this question



























      1












      1








      1








      I'm trying to automate switching out a bash prompt for another in .bashrc



      Original String:



      PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '


      Replacement Strings:



      IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
      PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '


      One of many poor attempts at writing bash to do so:



      #!/bin/bash
      original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '"
      replacement="PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '"
      ipvar="IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )"

      cp ~/.bashrc ~/.bashrc.bak
      sed -e 's/$original/$replacement/g' ~/.bashrc


      I've tried double escaping all of the characters because I know sed needs '','/', and '&' escaped. I just can't seem to wrap my head around this one.



      I didn't even bother trying to get the IP line in there right away because I couldn't replace the first line.



      If there are any better methods for this type of automation please let me know.










      share|improve this question
















      I'm trying to automate switching out a bash prompt for another in .bashrc



      Original String:



      PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '


      Replacement Strings:



      IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
      PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '


      One of many poor attempts at writing bash to do so:



      #!/bin/bash
      original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:[33[01;34m]w[33[00m]$ '"
      replacement="PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '"
      ipvar="IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )"

      cp ~/.bashrc ~/.bashrc.bak
      sed -e 's/$original/$replacement/g' ~/.bashrc


      I've tried double escaping all of the characters because I know sed needs '','/', and '&' escaped. I just can't seem to wrap my head around this one.



      I didn't even bother trying to get the IP line in there right away because I couldn't replace the first line.



      If there are any better methods for this type of automation please let me know.







      bash shell-script sed quoting string






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 11 hours ago









      Rui F Ribeiro

      41.3k1481140




      41.3k1481140










      asked May 9 '15 at 0:12









      daedalusdaedalus

      613




      613






















          1 Answer
          1






          active

          oldest

          votes


















          1














          Here are a couple of approaches (well, 2½):





          • If you’re interested in being able
            to incrementally modify PS1 settings that follow a general template,




            • Create a file that contains only the PS1=… line.

            • Write sed commands to edit it, piece by piece; e.g.,

              • sed -e 's/${debian_chroot:+($debian_chroot)}/\d \t /'

              • sed -e 's/\033/\e/g'

              • etc.



            • You might find it easier to debug these smaller, simpler commands. 
              When you’ve gotten them all working,
              it should be straightforward to stitch them together.




            • Have you looked at the value of $original
              E.g., have you done

                      printf "%sn" "$original"

              ?  Remember, when you say something like



              "The quick brown fox 'jumps over' the lazy dog."


              The entire string is in double quotes. 
              So when you say



              "Humpty '$var' Dumpty"


              The $var gets expanded, because it’s in double quotes.



              Now look at your original string:



              original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:…"


              The ${debian_chroot:+($debian_chroot)} gets expanded
              when you make that assignment.  So that’s a problem.






          • If you just want to change PS1 to your new value,
            regardless of what’s already there,
            don’t try to chisel down the statue of the fox
            and then add clay in the hopes of creating a statue of a dog;
            just blow away the existing assignment and replace it,
            using sed’s c (change) command,
            which replaces one group of one or more lines
            with another group of one or more lines:



            sed -e $'/^PS1=/c
            IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
            PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] ''


            I put the entire sed command string into $'…'
            so I could use ' to get raw ' characters into the string. 
            If you prefer, you can use the tried and true



            '$not_a_variable …'"… please don't try to expand those …"'… $not_a_variable'


            (quote alternation) technique.




          • A variant on the above is



            sed -e $'/^PS1=/{s/^/# /; a
            IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
            PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '
            }'


            which comments out the existing definition (s/^/# /)
            and appends the new lines with the a command.








          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',
            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%2f202349%2fusing-sed-to-replace-a-string-with-special-chars-with-another-string-with-specia%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Here are a couple of approaches (well, 2½):





            • If you’re interested in being able
              to incrementally modify PS1 settings that follow a general template,




              • Create a file that contains only the PS1=… line.

              • Write sed commands to edit it, piece by piece; e.g.,

                • sed -e 's/${debian_chroot:+($debian_chroot)}/\d \t /'

                • sed -e 's/\033/\e/g'

                • etc.



              • You might find it easier to debug these smaller, simpler commands. 
                When you’ve gotten them all working,
                it should be straightforward to stitch them together.




              • Have you looked at the value of $original
                E.g., have you done

                        printf "%sn" "$original"

                ?  Remember, when you say something like



                "The quick brown fox 'jumps over' the lazy dog."


                The entire string is in double quotes. 
                So when you say



                "Humpty '$var' Dumpty"


                The $var gets expanded, because it’s in double quotes.



                Now look at your original string:



                original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:…"


                The ${debian_chroot:+($debian_chroot)} gets expanded
                when you make that assignment.  So that’s a problem.






            • If you just want to change PS1 to your new value,
              regardless of what’s already there,
              don’t try to chisel down the statue of the fox
              and then add clay in the hopes of creating a statue of a dog;
              just blow away the existing assignment and replace it,
              using sed’s c (change) command,
              which replaces one group of one or more lines
              with another group of one or more lines:



              sed -e $'/^PS1=/c
              IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
              PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] ''


              I put the entire sed command string into $'…'
              so I could use ' to get raw ' characters into the string. 
              If you prefer, you can use the tried and true



              '$not_a_variable …'"… please don't try to expand those …"'… $not_a_variable'


              (quote alternation) technique.




            • A variant on the above is



              sed -e $'/^PS1=/{s/^/# /; a
              IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
              PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '
              }'


              which comments out the existing definition (s/^/# /)
              and appends the new lines with the a command.








            share|improve this answer




























              1














              Here are a couple of approaches (well, 2½):





              • If you’re interested in being able
                to incrementally modify PS1 settings that follow a general template,




                • Create a file that contains only the PS1=… line.

                • Write sed commands to edit it, piece by piece; e.g.,

                  • sed -e 's/${debian_chroot:+($debian_chroot)}/\d \t /'

                  • sed -e 's/\033/\e/g'

                  • etc.



                • You might find it easier to debug these smaller, simpler commands. 
                  When you’ve gotten them all working,
                  it should be straightforward to stitch them together.




                • Have you looked at the value of $original
                  E.g., have you done

                          printf "%sn" "$original"

                  ?  Remember, when you say something like



                  "The quick brown fox 'jumps over' the lazy dog."


                  The entire string is in double quotes. 
                  So when you say



                  "Humpty '$var' Dumpty"


                  The $var gets expanded, because it’s in double quotes.



                  Now look at your original string:



                  original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:…"


                  The ${debian_chroot:+($debian_chroot)} gets expanded
                  when you make that assignment.  So that’s a problem.






              • If you just want to change PS1 to your new value,
                regardless of what’s already there,
                don’t try to chisel down the statue of the fox
                and then add clay in the hopes of creating a statue of a dog;
                just blow away the existing assignment and replace it,
                using sed’s c (change) command,
                which replaces one group of one or more lines
                with another group of one or more lines:



                sed -e $'/^PS1=/c
                IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
                PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] ''


                I put the entire sed command string into $'…'
                so I could use ' to get raw ' characters into the string. 
                If you prefer, you can use the tried and true



                '$not_a_variable …'"… please don't try to expand those …"'… $not_a_variable'


                (quote alternation) technique.




              • A variant on the above is



                sed -e $'/^PS1=/{s/^/# /; a
                IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
                PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '
                }'


                which comments out the existing definition (s/^/# /)
                and appends the new lines with the a command.








              share|improve this answer


























                1












                1








                1







                Here are a couple of approaches (well, 2½):





                • If you’re interested in being able
                  to incrementally modify PS1 settings that follow a general template,




                  • Create a file that contains only the PS1=… line.

                  • Write sed commands to edit it, piece by piece; e.g.,

                    • sed -e 's/${debian_chroot:+($debian_chroot)}/\d \t /'

                    • sed -e 's/\033/\e/g'

                    • etc.



                  • You might find it easier to debug these smaller, simpler commands. 
                    When you’ve gotten them all working,
                    it should be straightforward to stitch them together.




                  • Have you looked at the value of $original
                    E.g., have you done

                            printf "%sn" "$original"

                    ?  Remember, when you say something like



                    "The quick brown fox 'jumps over' the lazy dog."


                    The entire string is in double quotes. 
                    So when you say



                    "Humpty '$var' Dumpty"


                    The $var gets expanded, because it’s in double quotes.



                    Now look at your original string:



                    original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:…"


                    The ${debian_chroot:+($debian_chroot)} gets expanded
                    when you make that assignment.  So that’s a problem.






                • If you just want to change PS1 to your new value,
                  regardless of what’s already there,
                  don’t try to chisel down the statue of the fox
                  and then add clay in the hopes of creating a statue of a dog;
                  just blow away the existing assignment and replace it,
                  using sed’s c (change) command,
                  which replaces one group of one or more lines
                  with another group of one or more lines:



                  sed -e $'/^PS1=/c
                  IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
                  PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] ''


                  I put the entire sed command string into $'…'
                  so I could use ' to get raw ' characters into the string. 
                  If you prefer, you can use the tried and true



                  '$not_a_variable …'"… please don't try to expand those …"'… $not_a_variable'


                  (quote alternation) technique.




                • A variant on the above is



                  sed -e $'/^PS1=/{s/^/# /; a
                  IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
                  PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '
                  }'


                  which comments out the existing definition (s/^/# /)
                  and appends the new lines with the a command.








                share|improve this answer













                Here are a couple of approaches (well, 2½):





                • If you’re interested in being able
                  to incrementally modify PS1 settings that follow a general template,




                  • Create a file that contains only the PS1=… line.

                  • Write sed commands to edit it, piece by piece; e.g.,

                    • sed -e 's/${debian_chroot:+($debian_chroot)}/\d \t /'

                    • sed -e 's/\033/\e/g'

                    • etc.



                  • You might find it easier to debug these smaller, simpler commands. 
                    When you’ve gotten them all working,
                    it should be straightforward to stitch them together.




                  • Have you looked at the value of $original
                    E.g., have you done

                            printf "%sn" "$original"

                    ?  Remember, when you say something like



                    "The quick brown fox 'jumps over' the lazy dog."


                    The entire string is in double quotes. 
                    So when you say



                    "Humpty '$var' Dumpty"


                    The $var gets expanded, because it’s in double quotes.



                    Now look at your original string:



                    original="PS1='${debian_chroot:+($debian_chroot)}[33[01;31m]u@h[33[00m]:…"


                    The ${debian_chroot:+($debian_chroot)} gets expanded
                    when you make that assignment.  So that’s a problem.






                • If you just want to change PS1 to your new value,
                  regardless of what’s already there,
                  don’t try to chisel down the statue of the fox
                  and then add clay in the hopes of creating a statue of a dog;
                  just blow away the existing assignment and replace it,
                  using sed’s c (change) command,
                  which replaces one group of one or more lines
                  with another group of one or more lines:



                  sed -e $'/^PS1=/c
                  IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
                  PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] ''


                  I put the entire sed command string into $'…'
                  so I could use ' to get raw ' characters into the string. 
                  If you prefer, you can use the tried and true



                  '$not_a_variable …'"… please don't try to expand those …"'… $not_a_variable'


                  (quote alternation) technique.




                • A variant on the above is



                  sed -e $'/^PS1=/{s/^/# /; a
                  IPeth0=$(Adr=$(ifconfig eth0 |grep inet); echo $Adr | awk '{print $2}' | cut -c 6- )
                  PS1='d t [e[0;31m]u@$IPeth0[e[0;32m]:[e[0;36m]w# [e[m] '
                  }'


                  which comments out the existing definition (s/^/# /)
                  and appends the new lines with the a command.









                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered May 9 '15 at 1:40









                G-ManG-Man

                13.4k93667




                13.4k93667






























                    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%2f202349%2fusing-sed-to-replace-a-string-with-special-chars-with-another-string-with-specia%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

                    Loup dans la culture

                    How to solve the problem of ntp “Unable to contact time server” from KDE?

                    Connection limited (no internet access)