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

Hi, i am working on a simple perl script to grab 3 variables based on a textfile. I am using regex. I tried to catch the word after the match string for the first variable, it works fine. But when i tried on the second variables, it appears error: Use of uninitialized value in print at enhancement.pl line 31, <$readhandle> line 4. I tried to put no warnings 'uninitialized';, but still the second output did not appear as expected. From the output file, only the name which is blocka appear whereas the path did not. Below are my code and the text file used.

#! /tools/perl/5.8.8/linux/bin/perl use strict; use warnings; print "Enter the name of the file to read: "; my $filetoread = <STDIN>; chomp($filetoread); print "Enter the name of the file to write: "; my $filetowrite = <STDIN>; chomp($filetowrite); open my $readhandle, "<", $filetoread or die "Unable to read '$filetor +ead'"; open my $writehandle, ">", $filetowrite or die "Unable to write '$file +towrite'"; my $name; my $path; while (<$readhandle>) { if ($_=~ m/^Name=(\S+)/) { $name = $1; print $writehandle $name; } if ($_=~ m/^Path=(\S+)/) { $path = $2; print $writehandle $path; } } close $readhandle; close $writehandle;

This is the textfile used

Name=blocka Path=/main/sub/a/bg/adee/swarfrw/ewqsx/fewaxr/akeil/awedr/date/file
  • Comment on error: Use of uninitialized value in print at enhancement.pl line 31, <$readhandle> line 4.
  • Select or Download Code

Replies are listed 'Best First'.
Re: error: Use of uninitialized value in print at enhancement.pl line 31, <$readhandle> line 4.
by hippo (Archbishop) on Jul 20, 2017 at 09:05 UTC

    The capture of the second match is not $2, it is $1. The higher numbered capture variables are set by multiple matches within the same regex only.

Re: error: Use of uninitialized value in print at enhancement.pl line 31, <$readhandle> line 4.
by thanos1983 (Parson) on Jul 20, 2017 at 11:28 UTC

    Hello mmazlan67,

    Well fellow monk hippo provided you with the answer to your problem already, but I would like to point out some things to your code just for your knowledge.

    Let's start. When you use die always use $! why? (from documentation)

    If an uncaught exception results in interpreter exit, the exit code is + determined from the values of $! and $?

    Moving on, when reading the file while (<$readhandle>) I would suggest always chomp $_; each line. The most important affect of chomp is that removes the new line characters \n it can produce problems or not desired output. Next step is that when you are using the general variable $_ you do not need to define it, Perl does this for you. For example, you do not need to define it like this chomp $_; you can do it straight like chomp;, same thing applies also on the if ($_=~ m/^Name=(\S+)/) you can do it straight like if (m/^Name=(\S+)/).

    Moving on, I noticed on your first if condition you define the regex without a space after the equal sign if ($_=~ m/^Name=(\S+)/) but on your input data file you have a space, so which one is the correct?

    Last thing that I noticed is that when you are writing on your file your are overwiriting it, if you want to appent it you need to use >>.

    I would also recommend to use the say. It automatically appends at the end of the string a new line character \n so you do not to be bothered to enter it when you are debugging or writing to a file.

    Any way based on my recommendations and correct solution provided by the fellow monk hippo here is a working version of your code.

    #!/usr/bin/perl use strict; use warnings; use feature 'say'; say "Enter the name of the file to read: "; my $filetoread = <STDIN>; chomp($filetoread); say "Enter the name of the file to write: "; my $filetowrite = <STDIN>; chomp($filetowrite); open my $readhandle, "<", $filetoread or die "Unable to read '$filetoread': $!"; open my $writehandle, ">>", $filetowrite or die "Unable to write '$filetowrite':$!"; while (<$readhandle>){ chomp; if (m/^Name=(\S+)/) { say $writehandle $1; } if (m/^Path=(\S+)/) { say $writehandle $1; } } close $readhandle or warn "Unable to close ".$filetoread.": $!"; close $writehandle or warn "Unable to close ".$filetowrite.": $!"; __END__ $ cat out.txt blocka /main/sub/a/bg/adee/swarfrw/ewqsx/fewaxr/akeil/awedr/date/file

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!