Sed Command – Replace Word After Significant Line and White Spaces

sedtext processing

I have the following text:

  A
  Hello
  world
  B
  Hello
  world
  C
  Hello
  world

I know that I can replace Hello by Hi using sed:

sed 's/Hello/Hi/g' -i test

but this replace each Hello with Hi:

  A
  Hi
  world
  B
  Hi
  world
  C
  Hi
  world

what I really want is to replace only the Hello after B:

  A
  Hello
  world
  B
  Hi
  world
  C
  Hello
  world

so I have tried this:

sed 's/"B\nHello"/"B\nHi"/g' -i test

but nothing happened, How can I do this?

Note: There are some white-spaces on the beginning of each line of the file.

Best Answer

Something like:

sed '/^[[:blank:]]*B$/{n;s/Hello/Hi/g;}'

That assumes there are no consecutive Bs (one B line followed by another B line).

Otherwise, you could do:

awk 'last ~ /^[[:blank:]]*B$/ {gsub("Hello", "Hi")}; {print; last=$0}'

The sed equivalent would be:

sed 'x;/^[[:blank:]]*B$/{
       g;s/Hello/Hi/;b
     }
     g'

To replace the second word after B, or to replace world with universe only if two lines above contained B:

awk 'l2 ~ /B/ {gsub("world","universe")}; {print; l2=l1; l1=$0}'

To generalise it to n lines above:

awk -v n=12 'l[NR%n] ~ /B/ {gsub("foo", "bar")}; {print; l[NR%n]=$0}'
Related Question