Reputation: 107
Im trying to extract part of a line with perl
use strict;
use warnings;
# Set path for my.txt and extract datadir
my @myfile = "C:\backups\MySQL\my.txt";
my @datadir = "";
open READMYFILE, @myfile or die "Error, my.txt not found.\n";
while (<READMYFILE>) {
# Read file and extract DataDir path
if (/C:\backups/gi) {
push @datadir, $_;
}
}
# ensure the path was found
print @datadir . " \n";
Basically at first im trying to set the location of the my.txt file. Next im trying to read it and pull part of the line with regex. The error Im getting is:
Unrecognized escape \m passed through at 1130.pl line 17.
I took a look at How can I grab multiple lines after a matching line in Perl? to get an idea of how to read a file and match a line within it, however im not 100% sure I'm doing this right or in the best way. I also seem to produce the error:
Error, my.txt not found.
But the file does exist in the folder C:\backups\MySQL\
Upvotes: 0
Views: 1328
Reputation: 171
Since there are several problems I'll put comments on the changes I've made in the code below.
use strict;
use warnings;
# For pretty dumping of arrays and what not.
use Data::Dumper;
# Use single quotes so you don't have to worry about escaping '\'s.
# Use a scalar ($) instead of an array(@) for storing the string.
my $myfile = 'C:\backups\MySQL\my.txt';
# No need to initialize the array.
my @datadir;
# I believe using a scalar is preferred for file handles.
# $! will contain the error if we couldn't open the file.
open(my $readmyfile, $myfile) or die "error opening: $!";
while (<$readmyfile>) {
# You must escape '\'s by doubling them.
# If you are just testing to see if the line contains 'c:\backups' you do not
# need /g for the regex. /g is for repeating matches
if (/C:\\backups/i) {
push(@datadir, $_);
}
}
# Data::Dumper would be better for dumping the array for debugging.
# Dumper wants a reference to the array.
print Dumper(\@datadir);
Update:
If you're referring to the output from Data::Dumper, it's just there for a pretty representation of the array. If you need a specifically formatted output you'll have to code it. A start would be:
print "$_\n" for (@datadir);
Upvotes: 4
Reputation: 3631
As other people have said, part of the issue is using " "
rather than ' '
type of quoting.
I try always to use ' '
unless I know I need to include an escape or interpolate a variable.
Here are a number of pitfalls
use 5.10.0 ;
use warnings ;
say "file is c:\mydir" ;
say "please pay $100 ";
say "on VMS the system directory is sys$system" ;
say "see you @5 ";
Unrecognized escape \m passed through at (eval 1) line 2.
Possible unintended interpolation of @5 in string at (eval 1) line 5.
file is c:mydir
Use of uninitialized value $100 in concatenation (.) or string at (eval 1) line 3.
please pay
Use of uninitialized value $system in concatenation (.) or string at (eval 1) line 4.
on VMS the system directory is sys
see you
file is c:\mydir
please pay $100
on VMS the system directory is sys$system
see you @5
Upvotes: 1
Reputation: 539
The file is not being found because you are passing an array to open
when it's expecting a scalar, so I'd guess that the array is being evaluated in a scalar context instead of as a list so you're actually telling perl to try opening the file named '1' instead of your 'my.txt' file.
Try something like this instead:
my $a = 'filename';
open FH, $a or die "Error, could not open $a: $!";
...
Upvotes: 1
Reputation: 2726
Shouldn't you be using $myfile
instead of @myfile
? The latter gives you an array, and since you're referencing it in scalar context, it's getting dereferenced (so it's actually trying to open a "file" called something like ARRAY(0xdeadbeef) instead of the actual filename).
Upvotes: 1
Reputation: 258128
When Perl sees the string "C:\backups\MySQL\my.txt"
it tries to parse any escape sequences, such as \n
. But when it sees \m
in \my.txt
, it's an unrecognized escape sequence, hence the error.
One way to fix this is to properly escape your backslashes: "C:\\backups\\MySQL\\my.txt"
. Another way to fix this is to use single quotes instead of double quotes: 'C:\backups\MySQL\my.txt'
. Yet another way is to use the q()
construct: q(C:\backups\MySQL\my.txt)
.
Upvotes: 4