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

I have a file abc.txt which contains below three lines

parameter,value

controller_name,bist_top_ctrl

support_18n,yes

I want to extract the string bist_top_ctrl

from this file

My code is below xyz.pl

use strict; use warnings; open(my $in, '<', $ARGV[0]) or die "Unable to open for read: $!"; while (my $line = <$in>) { while ( $line =~ /\controller_name,\s+(\w+)/g ) { my $fourth = $1; print "$fourth"; } } close $in;

Command to run :- perl xyz.pl abc.txt

I am not getting the string "bist_top_ctrl" at output

Where is the mistake ?

Replies are listed 'Best First'.
Re: Unable to retrieve the string bist_top_ctrl from a file
by jo37 (Curate) on May 22, 2021 at 13:18 UTC

    use \s* instead of \s+.

    Greetings,
    -jo

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
Re: Unable to retrieve the string bist_top_ctrl from a file
by kcott (Archbishop) on May 22, 2021 at 14:28 UTC

    In addition to what ++jo37 advised, the regex should probably

    • start with /^c; not /\c
    • end with )$/; not )/g

    See perlretut (tutorial) then perlre (details).

    — Ken

Re: Unable to retrieve the string bist_top_ctrl from a file
by AnomalousMonk (Archbishop) on May 22, 2021 at 15:24 UTC
    while ( $line =~ /\controller_name,\s+(\w+)/g ) { my $fourth = $1; print "$fourth"; }

    Also, this loop is rather suspect (and not just because of the rather bizarre indentation). Why not just use an if-conditional to do the extraction and printing? Then you won't be forced to use the /g modifier to keep the while-loop from running forever.

    Win8 Strawberry 5.8.9.5 (32) Sat 05/22/2021 11:10:41 C:\@Work\Perl\monks >perl -Mstrict -Mwarnings my $line = "controller_name,bist_top_ctrl\n"; if ($line =~ /controller_name,\s*(\w+)/) { my $fourth = $1; print "'$fourth' \n"; } ^Z 'bist_top_ctrl'


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

Re: Unable to retrieve the string bist_top_ctrl from a file
by hrcerq (Monk) on May 22, 2021 at 15:55 UTC

    Hi, aside from the other suggestions, you could also use split instead of a regex with a capture group, supposing this file will always be structured as a two-column CSV.

    while (my $line = <$in>) { my @fields = split /,/, $line; if ($fields[0] = "controller_name") { $fourth = $fields[1]; } }

    It could be further improved, but it's just so you get the picture.

    Update: The fields variable had the wrong sigil and wasn't lexical. Now corrected.

    return on_success() or die;