Reputation: 81
I'd to read a file, e.g. test.test
which contains
#test:testdescription\n
#cmd:binary\n
#return:0\n
#stdin:|\n
echo"toto"\n
echo"tata"\n
#stdout:|\n
toto\n
tata\n
#stderr:\n
I succeeded in taking which are after #test: ; #cmd: etc...
but for stdin
or stdout
, I want to take all the line before the next #
to a table @stdin
and @stdout
.
I do a loop while ($line = <TEST>)
so it will look at each line. If i see a pattern /^#stdin:|/
, I want to move to the next line and take this value to a
table until i see the next #
.
How do I move to the next line in the while
loop?
Upvotes: 1
Views: 513
Reputation: 129403
UPDATED as per user's colmments
If I understand the question correctly, you want to read one more line within a loop?
If so, you can either:
just do another line read inside the loop.
my $another_line = <TEST>;
Keep some state flag and use it next iteration of the loop, and accumulate lines between stdins in a buffer:
my $last_line_was_stdin = 0;
my @line_buffer = ();
while ($line = <TEST>) {
if (/^#stdin:|/) {
#
# Some Code to process all lines acccumulated since last "stdin"
#
@line_buffer = ();
$last_line_was_stdin = 1;
next;
}
push @line_buffer, $line;
}
This solution may not do 100% of what you need but it defines a pattern you need to follow in your state machine implementation: read a line. Check your current state (if it matters). Based on the current state and a pattern in the line, verify what do do about the current line (add to the buffer? change the state? If changing a state, process the buffer based on last state?)
Also, as per your comment, you have a bug in your regex - the pipe (|
character) means "OR" in regex, so you are saying "if line starts with #stdin
OR matches an empty regex" - the latter part is always true so your regex will match 100% of time. You need to escape the "|" via /^#stdin:\|/
or /^#stdin:[|]/
Upvotes: 1
Reputation: 118128
This file format can be easily handled with some creativity in selecting the appropriate value for $/
:
use strict; use warnings;
my %parsed;
{
local $/ = '#';
while ( my $line = <DATA> ) {
chomp $line;
my $content = (split /:/, $line, 2)[1];
next unless defined $content;
$content =~ s/\n+\z//;
if ( my ($chan) = $line =~ /^(std(?:err|in|out))/ ) {
$content =~ s/^\|\n//;
$parsed{$chan} = [ split /\n/, $content];
}
elsif ( my ($var) = $line =~ /^(cmd|return|test)/ ) {
$parsed{ $var } = $content;
}
}
}
use YAML;
print Dump \%parsed;
__DATA__
#test:testdescription
#cmd:binary
#return:0
#stdin:|
echo"toto"
echo"tata"
#stdout:|
toto
tata
#stderr:
Output:
--- cmd: binary return: 0 stderr: [] stdin: - echo"toto" - echo"tata" stdout: - toto - tata test: testdescription
Upvotes: 2