How to replace a whole line (between 2 words) using sed?

Solution for How to replace a whole line (between 2 words) using sed?
is Given Below:

Suppose I have text as:

This is a sample text.
I have 2 sentences.
text is present there.

I need to replace whole text between two ‘text’ words. The required solution should be

This is a sample text.
I have new sentences.
text is present there.

I tried using the below command but its not working:

sed -i 's/text.*?text/text
nI have new sentence/g' file.txt

With your shown samples please try following. sed doesn’t support lazy matching in regex. With awk‘s RS you could do the substitution with your shown samples only. You need to create variable val which has new value in it. Then in awk performing simple substitution operation will so the rest to get your expected output.

awk -v val="your_new_line_Value" -v RS="" '
{
  sub(/text.n*[^n]*n*text/,"text.n"val"ntext")
}
1
' Input_file

Above code will print output on terminal, once you are Happy with results of above and want to save output into Input_file itself then try following code.

awk -v val="your_new_line_Value" -v RS="" '
{
  sub(/text.n*[^n]*n*text/,"text.n"val"ntext")
}
1
' Input_file > temp && mv temp Input_file

You have already solved your problem using awk, but in case anyone else will be looking for a sed solution in the future, here’s a sed script that does what you needed. Granted, the script is using some advanced sed features, but that’s the fun part of it 🙂

replace.sed
#!/usr/bin/env sed -nEf

# This pattern determines the start marker for the range of lines where we
# want to perform the substitution. In our case the pattern is any line that
# ends with "text." — the `$` symbol meaning end-of-line.
/text.$/ {
  # [p]rint the start-marker line.
  p

  # Next, we'll read lines (using `n`) in a loop, so mark this point in
  # the script as the beginning of the loop using a label called `loop`.
  :loop

  # Read the next line.
  n

  # If the last read line doesn't match the pattern for the end marker,
  # just continue looping by [b]ranching to the `:loop` label.
  /^text/! {
    b loop
  }

  # If the last read line matches the end marker pattern, then just insert
  # the text we want and print the last read line. The net effect is that
  # all the previous read lines will be replaced by the inserted text.
  /^text/ {
    # Insert the replacement text
    i
I have a new sentence.

    # [print] the end-marker line
    p
  }

  # Exit the script, so that we don't hit the [p]rint command below.
  b
}

# Print all other lines.
p

Usage

$ cat lines.txt
foo
This is a sample text.
I have many sentences.
I have many sentences.
I have many sentences.
I have many sentences.
text is present there.
bar
$
$ ./replace.sed lines.txt
foo
This is a sample text.
I have a new sentence.
text is present there.
bar

Substitue

sed -i 's/I have 2 sentences./I have new sentences./g'

sed -i 's/[A-Z]s[a-z].*/I have new sentences./g'

Insert

sed -i -e '2iI have new sentences.' -e '2d'

I need to replace whole text between two 'text' words.

If I understand, first text. (with a dot) is at the end of first line and second text at the beginning of third line. With awk you can get the required solution adding values to var s:

awk -v s="nI have new sentences.n" '/text.?$/ {s=$0 s;next} /^text/ {s=s $0;print s;s=""}' file
This is a sample text.
I have new sentences.
text is present there.