2010-04-09 65 views
0

林提取数据试图用PerlPerl中,正则表达式,从线

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"; 

以提取线的部分基本上在第一即时试图设置My.txt文件文件的位置。接下来即时通讯尝试读取它,并与正则表达式的部分行。即时得到的错误是:

Unrecognized escape \m passed through at 1130.pl line 17.

我看了看How can I grab multiple lines after a matching line in Perl?获得如何读取文件,并匹配中有一条线的想法,但即时通讯不是100%肯定,我这样做的权利或最好的办法。我似乎也产生错误:

Error, my.txt not found.

但是文件在指定的文件夹存在C:\备份\的MySQL \

+0

未识别转义\米穿过在1130.pl线17已被分选这要归功于Mark Rushakoff和user275455的解决方案,我只需要在这里找不到my.txt文件的帮助,谢谢你说明了多种方法。 – perlnoob 2010-04-09 16:19:09

+0

到目前为止,我已经有几乎所有我需要的答案,我能够修复前面提到的错误,但是现在我似乎无法从它读取的行中删除DataDir,我尝试使用“pop”并读取数组中的我读取文件的方式也一样,但还没有奏效。 – perlnoob 2010-04-09 22:45:37

回答

4

当Perl中看到串"C:\backups\MySQL\my.txt"它会尝试解析任何转义序列,如\n。但是当它看到\m\my.txt时,它是一个无法识别的转义序列,因此是错误。

解决此问题的一种方法是正确地避免反斜杠:"C:\\backups\\MySQL\\my.txt"。解决这个问题的另一种方法是使用单引号而不是双引号:'C:\backups\MySQL\my.txt'。然而另一种的方式是使用q()构造:q(C:\backups\MySQL\my.txt)

+0

我试过你的解决方案,它也可以工作,但是我仍然遇到了“Error,my.txt not found”的问题,但是到目前为止,谢谢! – perlnoob 2010-04-09 16:18:12

+1

@perlnoob:你确定文件存在并且可读吗? – 2010-04-09 16:24:18

+0

是的,继承人是该目录的输出:C:\ backups \ mysql目录04/09/2010 08:40 AM

。 04/09/2010 08:40 AM .. 04/09/2010 08:45 AM 58 my.txt即使将它更改为perl脚本中的小写yeilds也不会改变。例如,如果我开始>运行并输入:C:/backups/MySQL/my.txt,它将打开带有文本文件的记事本 – perlnoob 2010-04-09 16:29:07

1

用正斜杠,而不是backslahes

+0

优秀,这照顾了“无法识别的逃脱\ m通过1130.pl线17”。错误,但我仍然没有得到“错误,my.txt没有找到。”仍然出于某种原因。 – perlnoob 2010-04-09 16:17:09

1

您不应该使用$myfile而不是@myfile?后者给你一个数组,因为你在标量上下文中引用它,所以它实际上是试图打开一个叫做“ARRAY(0xdeadbeef)”而不是实际文件名的“文件”。

1

该文件没有找到,因为当它期待一个标量时,你正在传递一个数组到open,所以我猜测数组是在标量上下文而不是列表中进行评估的,所以你实际上是在告诉perl尝试打开名为'1'的文件而不是'my.txt'文件。

尝试这样代替:

my $a = 'filename'; 
open FH, $a or die "Error, could not open $a: $!"; 
... 
4

因为有几个问题我会穿上我在下面的代码所做的修改意见。

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); 

更新:

如果你指的是从数据::自卸车的输出,它只是没有对数组的一个漂亮的表现。如果你需要一个专门格式化的输出,你必须编写它。一开始应该是:

print "$_\n" for (@datadir); 
+0

这几乎做了我想要的所有东西,但是我希望能够删除引号和它的“DataDir =”部分,但是到目前为止这是最好的答案。 – perlnoob 2010-04-09 22:39:23

1

至于其他人说,这个问题的一部分是用" "而不是' '类型引用的。 我总是尝试使用' ',除非我知道我需要包含转义或内插变量。 这里有一些陷阱的

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