First, most text-processing tools such as sed
or awk
work on a line-by-line basis, so matching entire paragraphs takes a little bit of extra effort. It is possible, but it is also one of the reasons for the unexpected output you are seeing.
Second, your input looks like structured text due to the XML-tag delimiting characters. As such, it might be best processed using xmlstarlet
or another dedicated tool. (Update: Since you confirmed this in a comment now, I would strongly recommend using xmlstarlet
or a similar tool.)
That said, if your text looks like in your example, and you have an awk
installation that accepts multi-character record separators (like GNU Awk), the following program should work:
awk -v RS="<|/>" '/2020/' input.txt
The RS
variable, if consisting of more than one character, will be interpreted as regular expression, so either a <
or a />
will be treated as "record separator", instead of the default \n
. Therefore, any matching conditions will apply to the entire text between these tags, and not just individual lines.
Result:
This is a line of text with a year=2020 month=12 in it
This line of text does not have a year or month in it
This year=2021 is the current year the current month=1
This is the year=2021 the month=2
Note that the "tag-open" <
and "tag-close" />
character combinations are stripped from the output because they are chosen as record separator. On the other hand, this means it will also work if the "paragraphs" are not separated by blank lines. (However, if there is "stray" text matching your pattern outside of such tags, it would also be matched.)
You would place the regular expression you are looking for inside the / ... /
part of the program (just as in a sed
adress statement). If you are looking for a fixed string, however, I would recommend
awk -v RS="<|/>" 'index($0,"2020")' input.txt
instead.
What am I doing wrong here?
You're not using an XML parser. stackoverflow.com/a/1732454/864696