2010-04-09 62 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