1

I'm currently working with a text file that contains the following text blocks:

--------------------------------------
Beginning of block
Text
Random Text
keywordA
Text
End of block
--------------------------------------

--------------------------------------
Beginning of block
Text
Random Text
keywordA
Text
End of block
--------------------------------------

--------------------------------------
Beginning of block
Text
Random Text
keywordD
Text
End of block
--------------------------------------

--------------------------------------
Beginning of block
Text
Random Text
keywordd
Text
End of block
--------------------------------------

The objective is to have egrep detect certain keywords, and if those words exist, I would like to copy the block to another file. So, I'm currently searching with:

if egrep -wi 'keywordA|KeywordB|keywordC' Report
then
        echo "Words found!"

else
        echo "No words found!"
fi

I was wondering if there is any way to add a follow up action to use sed (for example) to copy the block of text where the words were found.

Expected output, in this example, would be:

--------------------------------------
Beginning of block
Text
Random Text
keywordA
Text
End of block
--------------------------------------

--------------------------------------
Beginning of block
Text
Random Text
keywordA
Text
End of block
--------------------------------------

The file "Report" contains dozens of blocks like this, but not all of them have the keyword. I would like to copy just the ones that do (as demonstrated in the above example).

  • 1
    can you make your sample bigger to include more than one block (incl how they are separated like empty line or only those ---- ) and add expected output for that... awk with setting RS would be better suited... (also what is your version.. GNU awk, etc) – Sundeep Jun 4 '17 at 14:09
  • 2
    am sure this question has a duplicate somewhere... try awk -v RS= '/keywordA|KeywordB|keywordC/' Report – Sundeep Jun 4 '17 at 15:17
  • are there always 4 (or 6) lines of text in each block? – Jeff Schaller Jun 4 '17 at 16:46
  • No, the number of lines in each block varies. – t988GF Jun 4 '17 at 18:17
  • @Sundeep I only run a quick test, but it appears your suggestion worked exactly as expected!! Would you like to submit it as the answer? TY very much! – t988GF Jun 4 '17 at 19:04
2

it's so easy for magic awk command:

awk -v RS="--------------------------------------"
       '/keywordA/||/keywordB/||/keywordC/' RS='' infile.txt

You will get output as like below expected:

--------------------------------------
Beginning of block
Text
Random Text
keywordA
Text
End of block
--------------------------------------
--------------------------------------
Beginning of block
Text
Random Text
keywordA
Text
End of block
--------------------------------------
1

Maybe something along those lines will do:

awk '
    {
        if(/--------------------------------------/) {
            if(found)
                printf buffer
            buffer = ""
            found = 0
        } else
            buffer = buffer $0 "\n"
    }

    /keyworda|keywordb|whateveryouwant/ {
        found = 1
    }
' input_file.txt

Just adjust the keywords in the regexp near the end according to what you need. I store the lines in a variable, and when I reach a ----…---- line, if I encountered a wanted keyword, I print the content of this variable, then empty it and forget that I found an interesting keyword. I hope that's what you want. I can still edit it if needed, I guess.

This outputs interesting blocks to the standard output ; redirect the output to a file to copy them.

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.