#!/usr/bin/perl # blockgrep - print a key and its values, # where the key is on one line and each value is on a line # below the header, # optionally only printing blocks where the key and/or # value match a given pattern # # e.g., given a file: # ----- # heading1 # line1=foo # line2=bar # heading2 # line1=baz # ----- # # $ blockgrep -v 'foo' # # will print: # ----- # heading1 # line1=foo # ----- # # This uses the default of a key line starting in column 0 and value lines # being indented. # # If you need something else, use the -K and -V options, e.g., given a file: # ----- # key: key1 # value: value1 # # key: key2 # value: value2 # ----- # # try: # $ blockgrep -K '^key:' -V '^value:' ... use strict; use warnings; use Getopt::Long qw(:config no_ignore_case bundling); my $printallkeys = 0; my $printallvalues = 0; my $keypattern = '^\w'; my $valuepattern = '^\s+\S'; my $keyprintpattern = undef; # print all keys by default my $valueprintpattern = undef; # print all values by default sub usage { print STDERR <]... Options: -h Print this help message -k Print blocks where keys match (default all) -v Print blocks where values match (default all) -K Lines matching are keys (default $keypattern) -V Lines matching are values (default $valuepattern) Notes: If both -k and -v are specified, only blocks which match both are printed. EOF } GetOptions( "help|usage|h" => sub { usage, exit 0; }, "key-pattern|K=s" => \$keypattern, "value-pattern|V=s" => \$valuepattern, "key-print-pattern|k=s" => \$keyprintpattern, "value-print-pattern|v=s" => \$valueprintpattern ) or usage, exit 2; my $key; my $value; my $keywasprinted = 0; my $keymatched = 0; while (<>) { chomp; if (/$keypattern/) { $key = $_; $keywasprinted = 0; if (!defined($keyprintpattern) || /$keyprintpattern/) { $keymatched = 1; } else { $keymatched = 0; } } elsif (/$valuepattern/) { $value = $_; if (!defined($valueprintpattern) || /$valueprintpattern/) { if ($keymatched) { if (!$keywasprinted) { print $key . "\n"; $keywasprinted = 1; } print $value . "\n"; } } } }