I am working with a file structured like this:
Title1
- Quote
this is a quote
==========
Title1
- Note
this is a note
==========
Title1
- Quote
this is another quote
==========
Title1
- Note
this is another note
Each Title (Title1 Title2..) contains hundreds of quotes and some of those quotes have notes following them. Each specific note and quote is exactly 1 line. For a given Title I want to display "this is a quote" followed by "this is a note":
this is a quote
>> this is a note
--
this is another quote
>> this is another note
I came up with something like this:
grep -C 6 "Title1" | grep -B 3 -A 2 "Note" | egrep -v "Title1|=====|Note"
I got this result :
this is a quote
this is a note
--
this is another quote
this is another note
How do I format the text to achieve the results above? I am still new to Bash and wondering if there's a more efficient way to achieve this? I was experimenting with sed for this but I couldn't get it to work. Any help would be highly appreciated!
Edit: I should have been clearer about this. I'd like to clarify that "this is a quote" and "this is a note" contain different strings each time, while "Quote" and "Note" are the same throughout the file.
CodePudding user response:
If using awk
is an option:
awk -v title="Title1" '$0~title{f=1} /Quote/&&f==1{q=1} /Note/&&f==1{n=1} /====/{f=0;q=0;n=0} /^$/ && f==1 && q==1 {getline; print} /^$/ && f==1 && n==1 {getline; printf "%6s %s\n",">>",$0}' src.dat
this is a quote
>> this is a note
this is another quote
>> this is another note
-v title="Title1"
pass the target title as a variable to awk
$0~title{f=1}
set flag 'f' if current line matches target title.
/Quote/&&f==1{q=1}
set quote flag 'q' if title flag is set and current line matches 'Quote'.
/Note/&&f==1{n=1}
set note flag 'n' if title flag is set and current line matches 'Note'.
/^$/ && f==1 && q==1 {getline; print}
if current line is empty and title and quote flags are set, get the next line and print.
/^$/ && f==1 && n==1 {getline; printf "%6s %s\n",">>",$0}'
. if current line is empty and title and note flags are set, get the next line and print it as formatted output.
/====/{f=0;q=0;n=0}
clear flags if current line matches '===='.
contents of src.dat file used for testing:
Title1
- Quote
this is a quote
==========
Title1
- Note
this is a note
==========
Title1
- Quote
this is another quote
==========
Title1
- Note
this is another note