Sed substitute through a sentence on multiple lines

52,207

Solution 1

The following command will work in both situations:

sed '/Lorem.*/ {N; s/Lorem.*industry\./string to replace/g}' filename

More explanations: How can I use sed to replace a multi-line string?

Solution 2

While sed can match patterns on multiple lines (using the commands N or H to append successive lines before matching), this is well outside its comfort zone. Attempt it only if you like pain.

Perl can do this kind of things nicely. Use the -p switch to make it process standard input one record at a time and print the modified record (à la sed), and -000 to turn on paragraph mode (where records are separated by blank lines). In a regular expression, \s matches any whitespace character including a newline.

perl -p -000 -e 's/Lorem\s+Ipsum\s+is\s+simply\s+dummy\s+text\s+of\s+the\s+printing\s+and\s+typesetting\s+industry\./Replacement text/g'

If you want to put a newline in the replacement text when the original contains one, that's more complicated. How to do it depends on your requirements as to where to put the newline.

Solution 3

sed cannot easily read across multiple lines. Use perl -i -0pe 's/.../.../...' instead.

Share:
52,207
Ilia Hanev
Author by

Ilia Hanev

I am an evil overlord that is sometimes mis-judged. I love walks in the park under a lightning storm and driving around my Death Star through the Galaxy. People have been known to find me writing code for websites, light saber drawing in Illustrator on my Wacom, building apps to do something because I'm lazy or using the force to market my campaign on why the Rebels need to be demolished.

Updated on September 18, 2022

Comments

  • Ilia Hanev
    Ilia Hanev over 1 year

    I am new to using sed but I have been experimenting sed's s/..../..../ (substitute) to modify a full sentence if it's on one line but I am unaware an alternative solution on how to modify a sentence that may have been separated on two lines such as:

    This:

    Lorem Ipsum is simply dummy text of the printing and typesetting industry.
    

    is actually written as this:

    Lorem Ipsum is simply dummy text of the 
    printing and typesetting industry.
    

    How can you detect for this or code it to replace the entire sentence even if it's on two lines instead of one?

  • Radu Rădeanu
    Radu Rădeanu over 10 years
    sed can read across multiple lines!
  • h3.
    h3. over 10 years
    @RaduRădeanu Technically, yes. But it's rarely worth the trouble.
  • h3.
    h3. over 10 years
    @terdon Ah, I meant to allow multiple whitespace but forgot. Thanks, fixed.
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    @Gilles I understand your good intentions, but please try to test before to mess up my answer. Better, if you have another opinion, is to add another answer or to leave a comment.
  • h3.
    h3. over 10 years
    Welcome to Stack Exchange. This site is collaboratively edited. If you are not comfortable with the idea of your contributions being collaboratively edited by other trusted users, this may not be the site for you. I noticed that your code replaced more than the specific phrase that was intended, so I edited the phrase in.
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    @Gilles Please, you don't need to be mischievous. You should notice also that your "code" replaced absolutely nothing. As I said, I understand your good intentions. From my example I suppose that the OP to understand how to substitute through a sentence on multiple lines with sed, nothing more. And this is the title question. The title is not about perl.
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    @Gilles If using perl is more simple for you, this doesn't means that sed rarely worth the trouble.
  • Radu Rădeanu
    Radu Rădeanu over 10 years
    The question is about sed. It is also tagged with sed, not with perl.
  • h3.
    h3. over 10 years
    No, the code I posted does work. (Except if Lorem is on the last line, a defect it shares with your version.)
  • artnikpro
    artnikpro about 8 years
    This example is not working when there's 3 or more lines of text :(