I'm trying to scan a file for lines containing a specific string, and print the lines to another file.
However, I need to print out multiple lines until ")" character IF the line containing the string ended in "," ignoring whitespaces.
Currently I'm using
for func in $fnnames
do
sed/"$func"/p <$file >>$CODEBASEDIR/function_signature -n
done
where $func contains the string I look for, but of course it doesn't work for the restriction.
Is there a way to do this? Currently using bash, but perl is fine also. Thanks.
Your question is tricky because your restrictions are not precise. You say - I think - that a block should look like this:
foo,
bar,
baz)
Where foo
is the string that starts the block, and closing parenthesis ends it. However, you could also be saying:
foo bar baz) xxxxxxxxxxx,
And you only want to print until the )
, which is to say foo bar baz)
, IF the line ends with comma.
You could also be saying that only lines that end with a comma should be continued:
foo, # print + is continued
bar # print + is not continued
xxxxx # ignored line
foo # print + is not continued
foo,
bar,
baz) # closing parens also end block
Since I can only guess that you mean the first alternative, I give you two options:
use strict;
use warnings;
sub flip {
while (<DATA>) {
print if /^foo/ .. /\)\s*$/;
}
}
sub ifchain {
my ($foo, $print);
while (<DATA>) {
if (/^foo/) {
$foo = 1; # start block
print;
} elsif ($foo) {
if (/,\s*$/) {
print;
} elsif (/\)\s*$/) {
$foo = 0; # end block
print;
}
# for catching input errors:
else { chomp; warn "Mismatched line '$_'" }
}
}
}
__DATA__
foo1,
bar,
baz)
sadsdasdasdasd,
asda
adaffssd
foo2,
two,
three)
yada
The first one will print any lines found between a line starting with foo
and a line ending with )
. It will ignore the "lines end with comma" restriction. On the positive side, it can be simplified to a one-liner:
perl -ne 'print if /^foo/ .. /\)\s*$/' file.txt
The second one is just a simplistic if-structure that will consider both restrictions, and warn (print to STDERR) if it finds a line inside a block that does not match both.