sreek3502 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Experts,

I have "results.bat" file gives the output as below.

Student Name = Harry Student Code = student_id_1 Exam Status = PASSED ------------------------------------- Student Name = Mike Student Code = student_id_2 Exam Status = PASSED ------------------------------------- Student Name = Tom Student Code = student_id_3 Exam Status = PASSED -------------------------------------

I have written the below code to print the "Student Name & Exam status". But, all i need to print the result in horizontal as below. Please advise.

Expecting result:

Harry PASSED Mike PASSED Tom PASSED
use strict; use warnings; my ($sname,$result); my $cmd ="results.bat"; my @lines = `$cmd`; #print "@lines\n"; chomp (@lines); foreach my $line(@lines){ chomp ($line); if ($line =~ m/Student\sName\s+=\s(.*)/i){ chomp ($1); $sname =$1; print "$sname \n"; } if ($line =~ m/Exam\sStatus\s+=\s(.*)/i){ chomp ($1); $result =$1; print "$result \n"; } }

2018-01-16 Athanasius added code and paragraph tags

Replies are listed 'Best First'.
Re: Print the output results of matching line horizontally
by hippo (Archbishop) on Jan 14, 2018 at 15:39 UTC

    Have you tried just omitting the \n from each print statement?

Re: Print the output results of matching line horizontally
by Marshall (Canon) on Jan 14, 2018 at 21:05 UTC
    Can you add <code>...</code> tags around the input data from results.bat? That would be very helpful. I cannot tell what goes on each input line.

    Modify my DATA section below with the correct formatting.
    I made some assumptions about what the data looked like. I took out all of these chomp() statements as they are not necessary. Note that .* in a regex matches all characters except new line's. Also note that chomp @lines; is actually a foreach loop - don't do that if you are going to process each line individually again.

    #!/usr/bin/perl use strict; use warnings; my ($sname,$result); #my $cmd ="results.bat"; my @lines = <DATA>; #print "@lines\n"; #chomp (@lines); foreach my $line(@lines){ # chomp ($line); if ($line =~ m/Student\sName\s+=\s(.*)/i){ # chomp ($1); $sname =$1; print "$sname "; #changed } if ($line =~ m/Exam\sStatus\s+=\s(.*)/i){ # chomp ($1); $result =$1; print "$result "; #changed } } print "\n"; =Prints: Harry PASSED Mike PASSED Tom PASSED =cut __DATA__ Student Name = Harry Student Code = student_id_1 Exam Status = PASSED ------------------------------------- Student Name = Mike Student Code = student_id_2 Exam Status = PASSED ------------------------------------- Student Name = Tom Student Code = student_id_3 Exam Status = PASSED -------------------------------------
    I just made a small change to your print statement. I would have some other suggestions for you, but let's get the problem statement completely defined first. Your code although somewhat awkward basically "works".

    Update:
    I noticed that my DATA segment has some trailing spaces. That is probably not true of your actual input file. However a slight regex modification can handle this situation - a "minimal match" upon (.*) that allows for trailing blanks to be deleted. Here is some code for your consideration...

    #!/usr/bin/perl use strict; use warnings; while (my $line = <DATA>) { print "$1 " if $line =~ m/Student Name\s*=\s*(.*?)\s*$/; #deletes t +railing spaces print "$1 " if $line =~ m/Exam Status\s*=\s*(.*?)\s*$/; #deletes t +railing spaces } print "\n"; =Prints: Harry PASSED Mike PASSED Tom PASSED Bob Smith FAILED =cut __DATA__ Student Name = Harry Student Code = student_id_1 Exam Status = PASSED ------------------------------------- Student Name = Mike Student Code = student_id_2 Exam Status = PASSED ------------------------------------- Student Name = Tom Student Code = student_id_3 Exam Status = PASSED ------------------------------------- Student Name = Bob Smith Student Code = student_id_4 Exam Status=FAILED
    I can tell that you are very new to Perl. That is fine. And this is a good place to go. There is a limit to what can be conveyed in a single thread. If you read and learn more about chomp then I consider this instructional exercise a success.
Re: Print the output results of matching line horizontally
by NetWallah (Canon) on Jan 14, 2018 at 19:03 UTC
    >perl -ane 'm/Student Name\s+=\s+(\w+)/ and $name=$1; m/Exam Status\s+ +=\s+(\w+)/ and print qq{$name\t$1\n}' results.bat Harry PASSED Mike PASSED Tom PASSED
    If you are on Windows, use double quotes instead of single.

                    Is a computer language with goto's totally Wirth-less?

      >perl -ane '...' results.bat Harry PASSED Mike PASSED Tom PASSED

      But my understanding is that sreek3502 wants output something like:

      Harry PASSED Mike PASSED Tom PASSED


      Give a man a fish:  <%-{-{-{-<

        You may be right, and that's more or less what I think to understand, but it is far from clear because the original post lacks proper formatting.

        To the Original poster: please add <code> and </code> tags to both your input data sample and your desired result, so that we can really figure out what you need.

        I examined the raw HTML of the original post.

        It appears that the OP wanted each name on a separate line.

                        Is a computer language with goto's totally Wirth-less?

Re: Print the output results of matching line horizontally
by karlgoethebier (Abbot) on Jan 15, 2018 at 18:05 UTC

    My notorious 2˘:

    #!/usr/bin/env perl use strict; use warnings; use Path::Tiny; use Array::Split qw(split_by); use feature qw(say); use Data::Dump; my $file = shift; say path($file)->slurp; my @records; for ( split_by( 3, grep { defined } map { /(.+ = .+)/; $1 } path($file)->lines( { chomp => 1 } ) ) ) { my $name = ( split / = /, @$_[0] )[1]; my $code = ( split / = /, @$_[1] )[1]; my $status = ( split / = /, @$_[2] )[1]; printf( "%s %s\n", $name, $status ); my $hash_ref; $hash_ref->{name} = $name; $hash_ref->{status} = $status; $hash_ref->{code} = $code; push @records, $hash_ref; } dd \@records; __END__ karls-mac-mini:sreek3502 karl$ ./sreek3502.pl data.txt Student Name = Harry Student Code = student_id_1 Exam Status = PASSED ------------------------------------- Student Name = Mike Student Code = student_id_2 Exam Status = PASSED ------------------------------------- Student Name = Tom Student Code = student_id_3 Exam Status = PASSED ------------------------------------- Student Name = Bob Smith Student Code = student_id_4 Exam Status = FAILED Harry PASSED Mike PASSED Tom PASSED Bob Smith FAILED [ { code => "student_id_1", name => "Harry", status => "PASSED" }, { code => "student_id_2", name => "Mike", status => "PASSED" }, { code => "student_id_3", name => "Tom", status => "PASSED" }, { code => "student_id_4", name => "Bob Smith", status => "FAILED" }, ]

    Probably not the best or fastest solution but you get a AoH for free.

    Update: OK, horizontally: printf( "%s %s ", $name, $status );

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: Print the output results of matching line horizontally
by BillKSmith (Monsignor) on Jan 16, 2018 at 21:30 UTC
    Sorry about the late reply, but I just discovered a very short solution that you may like. I wrote a windows batch file which I believe simulates yours. The perl program executes the batch file and accepts its output. The -n switch takes care of all input and looping. The BEGIN block tells perl to open a socket to the batch file. The match parses the input and eliminates all lines that are not needed. One print statement prints all the data. A newline is printed after a status.
    C:\Users\Bill\forums\monks>type results.bat @echo off echo Student Name = Harry echo Student Code = student_id_1 echo Exam Status = PASSED echo ------------------------------------- echo Student Name = Mike echo Student Code = student_id_2 echo Exam Status = PASSED echo ------------------------------------- echo Student Name = Tom echo Student Code = student_id_3 echo Exam Status = PASSED echo ------------------------------------- C:\Users\Bill\forums\monks>type sreek350_2.pl #!perl -n use strict; use warnings; BEGIN{ unshift @ARGV, "results.bat |" } next unless /^(Student Name|Exam Status) +\= (.*)$/; printf "%-8s", $2; printf "\n" if ($1 eq 'Exam Status'); C:\Users\Bill\forums\monks>perl sreek350_2.pl Harry PASSED Mike PASSED Tom PASSED C:\Users\Bill\forums\monks>
    Bill
Re: Print the output results of matching line horizontally
by Anonymous Monk on Jan 14, 2018 at 16:25 UTC

    What does this mean?:

    my @lines = `$cmd`;