Reputation: 2343
I have a file structured like that:
BOF
-------Title1-------
stuff here
some stuff
-------Title2-------
extra things
extra things
extra things
-------Title3-------
and some stuff
here
...
-------Title4-------
stuff
EOF
Now I would like to do something like this:
grep-by-section KEYWORD DELIMITER my-file
so that
grep-by-section "some" "^---" my-file
outputs
-------Title1-------
stuff here
some stuff
-------Title3-------
and some stuff
here
I want to find a certain keyword and for every finding I want to output the whole block between known delimiters. How can I do that? sed
fails me here.
Delimiters here are "------", but could be something else like numbers in [0-9]{8} format for example.
A similar problem which I couldn't solve is instead of outputting the contents of the block, output just the title of the block.
It seems to be easier to solve with perl
than sed
Upvotes: 4
Views: 872
Reputation: 9936
If there are true empty lines between those records, you would not need to use those delimiters, this would suffice:
awk '/KEYWORD/' RS= ORS='\n\n' file
Otherwise you could also try this awk:
awk '
$0~key{
f=1
}
$0~del{
if(f)print s
f=0
s=$0
next
}
{
s=s RS $0
}
END{
if(f)print s
}
' key="KEYWORD" del="DELIMITER" file
In one line:
awk '$0~key{f=1} $0~del{ if(f)print s ; f=0; s=$0; next } {s=s RS $0} END{ if(f)print s }' key="KEYWORD" del="DELIMITER" file
Upvotes: 0
Reputation: 386416
#!/usr/bin/perl
my ($search, $del) = splice(@ARGV, 0, 2);
local $/;
while (<>) {
for (/($del(?:(?!$del).)*)/smg) {
print if /$search/sm;
}
}
Notes:
local $/
causes the following readline to read a file at a time instead of a line at a time.(?:(?!STRING).)*
is to STRING
as [^CHAR]*
is to CHAR
.Upvotes: 4