Search code examples
textawksedgnu

Cut matching line and X successive lines until newline and paste into file


I would like to match all lines from a file containing a word, and take all lines under until coming two two newline characters in a row.

I have the following sed code to cut and paste specific lines, but not subsequent lines:

sed 's|.*|/\\<&\\>/{w results\nd}|' teststring | sed -file.bak -f - testfile

How could I modify this to take all subsequent lines?

For example, say I wanted to match lines with 'dog', the following should take the first 3 lines of the 5:

The best kind of an animal is a dog, for sure
-man's best friend
-related to wolves

Racoons are not cute

Is there a way to do this?


Solution

  • This should do:

    awk '/dog/ {f=1} /^$/ {f=0} f {print > "new"} !f {print > "tmp"}' file && mv tmp file
    

    It will set f to true if word dog is found, then if a blank line is found set f to false.
    If f is true, print to new file.
    If f is false, print to tmp file.
    Copy tmp file to original file

    Edit: Can be shorten some:

    awk '/dog/ {f=1} /^$/ {f=0} {print > (f?"new":"tmp")}' file && mv tmp file
    

    Edit2: as requested add space for every section in the new file:

    awk '/dog/ {f=1;print ""> "new"} /^$/ {f=0} {print > (f?"new":"tmp")}' file && mv tmp file
    

    If the original files does contains tabs or spaces instead of just a blank line after each dog section, change from /^$/ to /^[ \t]*$/