2012-08-07 47 views
1

我正在嘗試開發一個perl腳本,該腳本通過全部查找特定文件名的用戶目錄,而用戶不必指定整個路徑名文件。Perl:在目錄中查找文件並將其分配給變量

例如,假設感興趣的文件是focus.qseq。它位於/home/path/directory/。在命令行中,通常用戶必須指定文件的路徑名才能訪問它,如下所示:/home/path/directory/focus.qseq

相反,我希望用戶只需在命令行中輸入sample.qseq,那麼perl腳本會自動將正確的文件分配給一個變量。如果文件是重複的,但在不同的目錄中,則終端將顯示這些文件的完整路徑名,用戶可以更好地指定它們的含義。

我讀了關於File::Find模塊,但它沒有做我想要的。

這裏是在我上述實施代碼我最好的嘗試:

#!/usr/bin/perl 
use strict; use warnings; 
use File::Find; 

my $file = shift; 

# I want to search from the top down (you know, recursively) so first I look in the home directory 
# I believe $ENV{HOME} is the same as $~/home/user 
find(\&wanted, @$ENV{HOME}); 
open (FILEIN, $file) or die "couldn't open $file for read: $!\n"; 

我真的不明白wanted子程序在此模塊中是如何工作的。如果有人知道另一種實現上述代碼的方式,請隨時提出建議。謝謝

編輯: 如果我想利用命令行選項怎麼辦?像這樣:

#!/usr/bin/perl 
use strict; use warnings; 
use File::Find; 
use Getopt::Long qw(GetOptions); 

my $file = ''; 
GetOptions('filename|f=s' => \$file); 

# I believe $ENV{HOME} is the same as $~/home/user 
find(\&wanted, @$ENV{HOME}); 
open (FILEIN, $file) or die "couldn't open $file for read: $!\n"; 

該實現將如何實現?

回答

1

一個問題是您嘗試打開文件時未指定路徑。您需要創建另一個變量,如$path。現在,您可以將\&wanted作爲您在別處編寫的子例程的參考,但是您可能不得不求助於全局變量。使用閉包會更好。

您的代碼可能是這樣的,那麼:

#!/usr/bin/perl 
use strict; use warnings; 
use File::Find; 
use Getopt::Long qw(GetOptions); 

my ($file, $path); 
GetOptions('filename|f=s' => \$file); 

# Set $path when file is found. 
my $wanted = sub { $path = $File::Find::name if ($_ eq $file); }; 

find($wanted, $ENV{HOME}); 
if (!$path) { 
    # complain 
} 
open (FILEIN, $path) or die "couldn't open $file for read: $!\n"; 
+0

我在'my $ wanted = sub {$ path = $ Find :: File :: name if ($ _ eq $ file); };'。該終端給我以下錯誤'名稱「查找::文件::名稱」只使用一次:在wrapper_example可能的錯字。pl line 17.' '/usr/share/perl/5.14/File/Find.pm第464行'無效的頂級目錄。'你知道'無效的頂級目錄'是什麼意思嗎? – cooldood3490 2012-08-07 14:13:07

+0

對不起,我寫了'Find :: File'而不是'File :: Find'。我在我的回答中糾正了它。 – Gingi 2012-08-07 14:23:07

+0

最初我把它當作'File :: Find',但是我得到了同樣的錯誤,所以我改變了'find($ wanted,@ $ ENV {HOME}。'/');'因爲我認爲'/ home/user/'和'$ ENV {HOME} /'相同。現在我收到權限錯誤。它說'不能cd到(/ var/spool/postfix /)active:權限在wrapper_example.pl第19行被拒絕' – cooldood3490 2012-08-07 14:31:48

2

File :: Find應該沒問題。

你可以通過一切迴路這樣

find(sub { 
    say $File::Find::name if ($_ eq $userInput); 
}, '/'); 

應該做你想做什麼。不要忘了chomp用戶輸入,除非它通過@ARGV

變化'/'到任何你想要的目錄來搜索,或者你可以讓用戶指定得過去了。

+0

,如果我想使用的命令行選項是什麼?所以在命令行我會輸入'perl script01.pl --filename focus.qseq'你能解釋一下上面的代碼是否會改變嗎? – cooldood3490 2012-08-07 13:51:50

+1

如果你想利用你的Perl腳本中的命令行選項,你應該使用'Getopt :: Long'模塊;它記錄得很好。如果你想將這些傳遞給shell,你可以使用'system()'調用或者使用反引號 – 2012-08-07 13:56:02

相關問題