2008-10-09 67 views
3

我有一個將文件句柄作爲參數的子例程。如何從命令行指定的文件路徑創建文件句柄?我不想自己對這個文件進行任何處理,我只是想把它傳遞給這個其他的子程序,它從文件中返回一個包含所有分析數據的散列數組。如何從命令行獲取文件句柄?

下面是我使用的是看起來像什麼命令行輸入:

$ ./getfile.pl /path/to/some/file.csv

這裏是我打電話的樣子子程序的開頭是什麼:

sub parse { 
    my $handle = shift; 
    my @data = <$handle>; 
    while (my $line = shift(@data)) { 
     # do stuff 
    } 
} 
+0

你沒有文件句柄,你有一個文件*名稱*。子程序期望什麼? – 2008-10-09 21:36:55

+0

我已經更新了您的問題。 – cowgod 2008-10-09 21:47:48

回答

16

命令行參數在預定義的@ARGV數組中可用。您可以從那裏獲取文件名並使用open打開文件句柄。假設你想只讀訪問該文件,你會做這種方式:

my $file = shift @ARGV; 
open(my $fh, '<', $file) or die "Can't read file '$file' [$!]\n"; 
parse($fh); 

注意,or die...檢查通話open成功並錯誤消息死去,如果它不是。內置變量$!將在失敗時包含(操作系統相關)錯誤消息,告訴您呼叫未成功的原因。例如「沒有權限。」

-1

我錯過或者你只是在尋找open()調用?

open($fh, "<$ARGV[0]") or die "couldn't open $ARGV[0]: $!"; 
do_something_with_fh($fh); 
close($fh); 
+0

這是錯誤的。它打開我的$ fh,「<$ ARGV [0]」。 $ fh是第一個參數,而不是返回值! (或更好地打開我的$ fh,'<',$ ARGV [0]。 – 2008-10-09 21:41:45

+0

固定,謝謝你的提示 – bmdhacks 2008-10-09 23:20:14

5

parse(*ARGV)是最簡單的解決方案:解釋有點長,但學習如何有效地使用Perl的一個重要部分是學習Perl。

當你使用一個空文件句柄(<>),它實際上從神奇ARGV文件句柄,它具有特殊的語義內容如下:從所有@ARGV命名的文件中讀取,或STDIN如果@ARGV是空的。

perldoc perlop

的空文件句柄<>是特殊的:它可以用來模擬的sed和awk的 行爲。來自<>的輸入來自標準 輸入,或來自命令行上列出的每個文件。下面是它如何工作 :第一次<>進行評估時,@ARGV陣列進行檢查,並 如果是空的,$ARGV[0]設置爲"-",它打開時給你 標準輸入。 @ARGV數組然後被處理爲 文件名列表。循環

while (<>) { 
    ...      # code for each line 
} 

相當於下面的Perl般的僞代碼:

unshift(@ARGV, '-') unless @ARGV; 
while ($ARGV = shift) { 
    open(ARGV, $ARGV); 
    while (<ARGV>) { 
     ...   # code for each line 
    } 
} 

但它並非如此繁瑣的說,而且會實際工作。它 確實會移動@ARGV數組,並將當前文件名放入 $ARGV變量中。它也在內部使用文件句柄ARGV - <>只是 的同義詞<ARGV>,這是神奇的。 (上面的僞代碼不 工作,因爲它把<ARGV>非神奇。)

您不必使用<>while環 - my $data = <>會從第一個非讀取一行空文件,my @data = <>;將立即全部提供,您可以通過*ARGV,就好像它是一個正常的文件句柄。

1

這就是-n開關的用途!

把你的解析方法,並做到這一點:

#!/usr/bin/perl -n 

#do stuff 

每一行存儲在$ _。所以,你運行

./getfile.pl /path/to.csv

而且它這樣做。

有關這些的更多信息,請參閱herehere。我也喜歡-p,並且發現-a和-F的組合非常有用。

此外,如果你想做一些額外的處理,添加BEGIN和結束塊。

#!/usr/bin/perl -n 

BEGIN { 
    my $accumulator; 
} 

# do stuff 

END { 
    print process_total($accumulator); 
} 

或其他。這非常非常有用。