I have a file which contains following content,

Hello world Unix!!
Its bright world
Current time is HH:mm:ss
Next action plan is item #3
End of task.
Thank you.

Hello world Linux!!
All actions completed.
End of Activity.

I would like to selectively delete all the lines that contain keyword, "world" and also all the subsequent lines until a line with specific set of keywords (Example, "Activity" or "task") are encountered.

Desired output :

End of task.
Thank you.
End of Activity.
  • 1
    what happened to the blank lines? They weren't between a (new) "world" and "activity" or "task". – Jeff Schaller May 30 at 20:04
  • Blank lines can be retained or deleted. – user2487274 May 30 at 21:18


$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f' File
End of task.
Thank you.

End of Activity.

How it works:

  1. -v f=1

    Create an awk variable f and set it to 1.

  2. /world/{f=0}

    If the current line contains world, set variable f to zero.

  3. /Activity|task/{f=1}

    If the line contains either Activity or task, then set f to 1.

    Note that world above and Activity or task here are treated as regular expressions. Also, they are case-sensitive.

  4. f

    If f is nonzero, print the line.

To also delete blank lines

$ awk  -v f=1 '/world/{f=0} /Activity|task/{f=1} f && /./' File
End of task.
Thank you.
End of Activity.

f && /./ tells awk to print the line only if f is non-zero and the line contains at least one character (of any kind).


Not as pretty as the awk solution, but since the OP tagged the question with sed too, here goes:

#with blank lines
sed '/world/,/task\|Activity/{//!d};/world/d' file

#without blank lines
sed '/world/,/task\|Activity/{//!d};/world\|^$/d' file

Note the use of //, which means the previous regular expression used :)

  • Nice use of //. – John1024 Jun 1 at 19:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.