2012-08-07 45 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

相关问题