Gnu Sed: Space Character class not matching for end of line character

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












0














Pattern: abc followed by space or is the last character in a line.



orig="abc[[:space:]]+";
new=Hello
sed -i -r -e "s|$orig|$new|g" ./file ;


File:



abc
abcd
abc

abc d


After executing:



abc
abcd
abc

Hellod


Expected Output:



Hello
abcd
Hello

Hello d


What am I missing?




Note: I want to preserve the space character.










share|improve this question























  • I noticed that you said "Pattern: abc followed by space or is the last character in a line" but then showed abc d being translated to Hellod when "abc(space)" was not the end of line -- d is. Which rule is correct? abc(spaces) or abc(spaces)(end of line)?
    – Jeff Schaller
    Dec 11 at 0:37






  • 1




    Perhaps what you are looking for is a word boundary anchor? s/abcb/Hello/ or (GNU sed) s/abc>/Hello/
    – steeldriver
    Dec 11 at 0:47















0














Pattern: abc followed by space or is the last character in a line.



orig="abc[[:space:]]+";
new=Hello
sed -i -r -e "s|$orig|$new|g" ./file ;


File:



abc
abcd
abc

abc d


After executing:



abc
abcd
abc

Hellod


Expected Output:



Hello
abcd
Hello

Hello d


What am I missing?




Note: I want to preserve the space character.










share|improve this question























  • I noticed that you said "Pattern: abc followed by space or is the last character in a line" but then showed abc d being translated to Hellod when "abc(space)" was not the end of line -- d is. Which rule is correct? abc(spaces) or abc(spaces)(end of line)?
    – Jeff Schaller
    Dec 11 at 0:37






  • 1




    Perhaps what you are looking for is a word boundary anchor? s/abcb/Hello/ or (GNU sed) s/abc>/Hello/
    – steeldriver
    Dec 11 at 0:47













0












0








0


0





Pattern: abc followed by space or is the last character in a line.



orig="abc[[:space:]]+";
new=Hello
sed -i -r -e "s|$orig|$new|g" ./file ;


File:



abc
abcd
abc

abc d


After executing:



abc
abcd
abc

Hellod


Expected Output:



Hello
abcd
Hello

Hello d


What am I missing?




Note: I want to preserve the space character.










share|improve this question















Pattern: abc followed by space or is the last character in a line.



orig="abc[[:space:]]+";
new=Hello
sed -i -r -e "s|$orig|$new|g" ./file ;


File:



abc
abcd
abc

abc d


After executing:



abc
abcd
abc

Hellod


Expected Output:



Hello
abcd
Hello

Hello d


What am I missing?




Note: I want to preserve the space character.







text-processing sed gnu whitespace






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 11 at 0:00









Jeff Schaller

38.3k1053125




38.3k1053125










asked Dec 10 at 23:25









Nikhil

24319




24319











  • I noticed that you said "Pattern: abc followed by space or is the last character in a line" but then showed abc d being translated to Hellod when "abc(space)" was not the end of line -- d is. Which rule is correct? abc(spaces) or abc(spaces)(end of line)?
    – Jeff Schaller
    Dec 11 at 0:37






  • 1




    Perhaps what you are looking for is a word boundary anchor? s/abcb/Hello/ or (GNU sed) s/abc>/Hello/
    – steeldriver
    Dec 11 at 0:47
















  • I noticed that you said "Pattern: abc followed by space or is the last character in a line" but then showed abc d being translated to Hellod when "abc(space)" was not the end of line -- d is. Which rule is correct? abc(spaces) or abc(spaces)(end of line)?
    – Jeff Schaller
    Dec 11 at 0:37






  • 1




    Perhaps what you are looking for is a word boundary anchor? s/abcb/Hello/ or (GNU sed) s/abc>/Hello/
    – steeldriver
    Dec 11 at 0:47















I noticed that you said "Pattern: abc followed by space or is the last character in a line" but then showed abc d being translated to Hellod when "abc(space)" was not the end of line -- d is. Which rule is correct? abc(spaces) or abc(spaces)(end of line)?
– Jeff Schaller
Dec 11 at 0:37




I noticed that you said "Pattern: abc followed by space or is the last character in a line" but then showed abc d being translated to Hellod when "abc(space)" was not the end of line -- d is. Which rule is correct? abc(spaces) or abc(spaces)(end of line)?
– Jeff Schaller
Dec 11 at 0:37




1




1




Perhaps what you are looking for is a word boundary anchor? s/abcb/Hello/ or (GNU sed) s/abc>/Hello/
– steeldriver
Dec 11 at 0:47




Perhaps what you are looking for is a word boundary anchor? s/abcb/Hello/ or (GNU sed) s/abc>/Hello/
– steeldriver
Dec 11 at 0:47










2 Answers
2






active

oldest

votes


















1














If what you want is to preserve spaces:




Note: I want to preserve the space character.




Then, match them, but restore them on the replacement:



 orig='abc([[:space:]]+)'
new='Hello1'
sed -E -e "s|$orig|$new|g" ./infile ;


That will generate this output (to modify in-place add the appropriate -i option):



 Hello 
abcd
Hello

Hello d


Of course, that is assuming the file had some spaces at the end of some lines:



 $ cat infile | sed -n l
abc $
abcd $
abc $
$
abc d$


If you also need that the regex match lines that do not end on spaces, you need a more complex regex:



 orig='abc([[:space:]]+|$)';
new='Hello1';
sed -E -e "s,$orig,$new,g" ./infile ;


Of course, the s||| delimiter had to be changed to s,,, to avoid conflicts with the | required by the regex for alternative.






share|improve this answer




















  • Why do we have to add |$? According to sed, a stream editor: Character Classes and Bracket Expressions : Space characters: in the ‘C’ locale, this is tab, newline, vertical tab, form feed, carriage return, and space.
    – Nikhil
    Dec 11 at 8:55






  • 1




    (1) I tried to match your words: space or is the last character in a line. The only way to tell a regex to match the end of a line is $, no other. The syntax fo an or is |, so that is what I wrote. IF you meant: several spaces or none, the regex would have been abc([[:space:]]*$), no | needed, but the end of line is still required. (Cont...) @Nikhil
    – Isaac
    Dec 11 at 9:07







  • 1




    (2) There is no way to match a newline in grep (BRE, ERE or most pcre without a -z option used). That is also said in info grep: Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text. So, the character range may (in some OSes) match a newline but there is never a newline to match in most grep text (exception noted above with grep -Pz or some other corner case uses). @Nikhil
    – Isaac
    Dec 11 at 9:08


















1














Instead of matching, capturing and then re-inserting the whitespace, just look for "abc" as a standalone word. With GNU sed, use < and > as word boundaries:



sed 's/<abc>/Hello/g' file




Hello
abcd
Hello

Hello d


If you want to put the pattern and replacement into variables, you just have to be careful to quote the backslashes appropriately.



pattern="\<abc\>" # or: pattern='<abc>'
replacement=Hello
sed "s/$pattern/$replacement/" file





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%2f487234%2fgnu-sed-space-character-class-not-matching-for-end-of-line-character%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    If what you want is to preserve spaces:




    Note: I want to preserve the space character.




    Then, match them, but restore them on the replacement:



     orig='abc([[:space:]]+)'
    new='Hello1'
    sed -E -e "s|$orig|$new|g" ./infile ;


    That will generate this output (to modify in-place add the appropriate -i option):



     Hello 
    abcd
    Hello

    Hello d


    Of course, that is assuming the file had some spaces at the end of some lines:



     $ cat infile | sed -n l
    abc $
    abcd $
    abc $
    $
    abc d$


    If you also need that the regex match lines that do not end on spaces, you need a more complex regex:



     orig='abc([[:space:]]+|$)';
    new='Hello1';
    sed -E -e "s,$orig,$new,g" ./infile ;


    Of course, the s||| delimiter had to be changed to s,,, to avoid conflicts with the | required by the regex for alternative.






    share|improve this answer




















    • Why do we have to add |$? According to sed, a stream editor: Character Classes and Bracket Expressions : Space characters: in the ‘C’ locale, this is tab, newline, vertical tab, form feed, carriage return, and space.
      – Nikhil
      Dec 11 at 8:55






    • 1




      (1) I tried to match your words: space or is the last character in a line. The only way to tell a regex to match the end of a line is $, no other. The syntax fo an or is |, so that is what I wrote. IF you meant: several spaces or none, the regex would have been abc([[:space:]]*$), no | needed, but the end of line is still required. (Cont...) @Nikhil
      – Isaac
      Dec 11 at 9:07







    • 1




      (2) There is no way to match a newline in grep (BRE, ERE or most pcre without a -z option used). That is also said in info grep: Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text. So, the character range may (in some OSes) match a newline but there is never a newline to match in most grep text (exception noted above with grep -Pz or some other corner case uses). @Nikhil
      – Isaac
      Dec 11 at 9:08















    1














    If what you want is to preserve spaces:




    Note: I want to preserve the space character.




    Then, match them, but restore them on the replacement:



     orig='abc([[:space:]]+)'
    new='Hello1'
    sed -E -e "s|$orig|$new|g" ./infile ;


    That will generate this output (to modify in-place add the appropriate -i option):



     Hello 
    abcd
    Hello

    Hello d


    Of course, that is assuming the file had some spaces at the end of some lines:



     $ cat infile | sed -n l
    abc $
    abcd $
    abc $
    $
    abc d$


    If you also need that the regex match lines that do not end on spaces, you need a more complex regex:



     orig='abc([[:space:]]+|$)';
    new='Hello1';
    sed -E -e "s,$orig,$new,g" ./infile ;


    Of course, the s||| delimiter had to be changed to s,,, to avoid conflicts with the | required by the regex for alternative.






    share|improve this answer




















    • Why do we have to add |$? According to sed, a stream editor: Character Classes and Bracket Expressions : Space characters: in the ‘C’ locale, this is tab, newline, vertical tab, form feed, carriage return, and space.
      – Nikhil
      Dec 11 at 8:55






    • 1




      (1) I tried to match your words: space or is the last character in a line. The only way to tell a regex to match the end of a line is $, no other. The syntax fo an or is |, so that is what I wrote. IF you meant: several spaces or none, the regex would have been abc([[:space:]]*$), no | needed, but the end of line is still required. (Cont...) @Nikhil
      – Isaac
      Dec 11 at 9:07







    • 1




      (2) There is no way to match a newline in grep (BRE, ERE or most pcre without a -z option used). That is also said in info grep: Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text. So, the character range may (in some OSes) match a newline but there is never a newline to match in most grep text (exception noted above with grep -Pz or some other corner case uses). @Nikhil
      – Isaac
      Dec 11 at 9:08













    1












    1








    1






    If what you want is to preserve spaces:




    Note: I want to preserve the space character.




    Then, match them, but restore them on the replacement:



     orig='abc([[:space:]]+)'
    new='Hello1'
    sed -E -e "s|$orig|$new|g" ./infile ;


    That will generate this output (to modify in-place add the appropriate -i option):



     Hello 
    abcd
    Hello

    Hello d


    Of course, that is assuming the file had some spaces at the end of some lines:



     $ cat infile | sed -n l
    abc $
    abcd $
    abc $
    $
    abc d$


    If you also need that the regex match lines that do not end on spaces, you need a more complex regex:



     orig='abc([[:space:]]+|$)';
    new='Hello1';
    sed -E -e "s,$orig,$new,g" ./infile ;


    Of course, the s||| delimiter had to be changed to s,,, to avoid conflicts with the | required by the regex for alternative.






    share|improve this answer












    If what you want is to preserve spaces:




    Note: I want to preserve the space character.




    Then, match them, but restore them on the replacement:



     orig='abc([[:space:]]+)'
    new='Hello1'
    sed -E -e "s|$orig|$new|g" ./infile ;


    That will generate this output (to modify in-place add the appropriate -i option):



     Hello 
    abcd
    Hello

    Hello d


    Of course, that is assuming the file had some spaces at the end of some lines:



     $ cat infile | sed -n l
    abc $
    abcd $
    abc $
    $
    abc d$


    If you also need that the regex match lines that do not end on spaces, you need a more complex regex:



     orig='abc([[:space:]]+|$)';
    new='Hello1';
    sed -E -e "s,$orig,$new,g" ./infile ;


    Of course, the s||| delimiter had to be changed to s,,, to avoid conflicts with the | required by the regex for alternative.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 11 at 6:43









    Isaac

    11k11648




    11k11648











    • Why do we have to add |$? According to sed, a stream editor: Character Classes and Bracket Expressions : Space characters: in the ‘C’ locale, this is tab, newline, vertical tab, form feed, carriage return, and space.
      – Nikhil
      Dec 11 at 8:55






    • 1




      (1) I tried to match your words: space or is the last character in a line. The only way to tell a regex to match the end of a line is $, no other. The syntax fo an or is |, so that is what I wrote. IF you meant: several spaces or none, the regex would have been abc([[:space:]]*$), no | needed, but the end of line is still required. (Cont...) @Nikhil
      – Isaac
      Dec 11 at 9:07







    • 1




      (2) There is no way to match a newline in grep (BRE, ERE or most pcre without a -z option used). That is also said in info grep: Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text. So, the character range may (in some OSes) match a newline but there is never a newline to match in most grep text (exception noted above with grep -Pz or some other corner case uses). @Nikhil
      – Isaac
      Dec 11 at 9:08
















    • Why do we have to add |$? According to sed, a stream editor: Character Classes and Bracket Expressions : Space characters: in the ‘C’ locale, this is tab, newline, vertical tab, form feed, carriage return, and space.
      – Nikhil
      Dec 11 at 8:55






    • 1




      (1) I tried to match your words: space or is the last character in a line. The only way to tell a regex to match the end of a line is $, no other. The syntax fo an or is |, so that is what I wrote. IF you meant: several spaces or none, the regex would have been abc([[:space:]]*$), no | needed, but the end of line is still required. (Cont...) @Nikhil
      – Isaac
      Dec 11 at 9:07







    • 1




      (2) There is no way to match a newline in grep (BRE, ERE or most pcre without a -z option used). That is also said in info grep: Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text. So, the character range may (in some OSes) match a newline but there is never a newline to match in most grep text (exception noted above with grep -Pz or some other corner case uses). @Nikhil
      – Isaac
      Dec 11 at 9:08















    Why do we have to add |$? According to sed, a stream editor: Character Classes and Bracket Expressions : Space characters: in the ‘C’ locale, this is tab, newline, vertical tab, form feed, carriage return, and space.
    – Nikhil
    Dec 11 at 8:55




    Why do we have to add |$? According to sed, a stream editor: Character Classes and Bracket Expressions : Space characters: in the ‘C’ locale, this is tab, newline, vertical tab, form feed, carriage return, and space.
    – Nikhil
    Dec 11 at 8:55




    1




    1




    (1) I tried to match your words: space or is the last character in a line. The only way to tell a regex to match the end of a line is $, no other. The syntax fo an or is |, so that is what I wrote. IF you meant: several spaces or none, the regex would have been abc([[:space:]]*$), no | needed, but the end of line is still required. (Cont...) @Nikhil
    – Isaac
    Dec 11 at 9:07





    (1) I tried to match your words: space or is the last character in a line. The only way to tell a regex to match the end of a line is $, no other. The syntax fo an or is |, so that is what I wrote. IF you meant: several spaces or none, the regex would have been abc([[:space:]]*$), no | needed, but the end of line is still required. (Cont...) @Nikhil
    – Isaac
    Dec 11 at 9:07





    1




    1




    (2) There is no way to match a newline in grep (BRE, ERE or most pcre without a -z option used). That is also said in info grep: Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text. So, the character range may (in some OSes) match a newline but there is never a newline to match in most grep text (exception noted above with grep -Pz or some other corner case uses). @Nikhil
    – Isaac
    Dec 11 at 9:08




    (2) There is no way to match a newline in grep (BRE, ERE or most pcre without a -z option used). That is also said in info grep: Since newline is also a separator for the list of patterns, there is no way to match newline characters in a text. So, the character range may (in some OSes) match a newline but there is never a newline to match in most grep text (exception noted above with grep -Pz or some other corner case uses). @Nikhil
    – Isaac
    Dec 11 at 9:08













    1














    Instead of matching, capturing and then re-inserting the whitespace, just look for "abc" as a standalone word. With GNU sed, use < and > as word boundaries:



    sed 's/<abc>/Hello/g' file




    Hello
    abcd
    Hello

    Hello d


    If you want to put the pattern and replacement into variables, you just have to be careful to quote the backslashes appropriately.



    pattern="\<abc\>" # or: pattern='<abc>'
    replacement=Hello
    sed "s/$pattern/$replacement/" file





    share|improve this answer

























      1














      Instead of matching, capturing and then re-inserting the whitespace, just look for "abc" as a standalone word. With GNU sed, use < and > as word boundaries:



      sed 's/<abc>/Hello/g' file




      Hello
      abcd
      Hello

      Hello d


      If you want to put the pattern and replacement into variables, you just have to be careful to quote the backslashes appropriately.



      pattern="\<abc\>" # or: pattern='<abc>'
      replacement=Hello
      sed "s/$pattern/$replacement/" file





      share|improve this answer























        1












        1








        1






        Instead of matching, capturing and then re-inserting the whitespace, just look for "abc" as a standalone word. With GNU sed, use < and > as word boundaries:



        sed 's/<abc>/Hello/g' file




        Hello
        abcd
        Hello

        Hello d


        If you want to put the pattern and replacement into variables, you just have to be careful to quote the backslashes appropriately.



        pattern="\<abc\>" # or: pattern='<abc>'
        replacement=Hello
        sed "s/$pattern/$replacement/" file





        share|improve this answer












        Instead of matching, capturing and then re-inserting the whitespace, just look for "abc" as a standalone word. With GNU sed, use < and > as word boundaries:



        sed 's/<abc>/Hello/g' file




        Hello
        abcd
        Hello

        Hello d


        If you want to put the pattern and replacement into variables, you just have to be careful to quote the backslashes appropriately.



        pattern="\<abc\>" # or: pattern='<abc>'
        replacement=Hello
        sed "s/$pattern/$replacement/" file






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 11 at 18:35









        glenn jackman

        50.1k569106




        50.1k569106



























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f487234%2fgnu-sed-space-character-class-not-matching-for-end-of-line-character%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

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

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay