如何在Perl中查找与提示输入匹配的文件而不使用-e和-d。。。文件::找到唯一的方法?
下午好,朋友们 我被分配了以下任务,希望学习如何查看文件或目录是否存在 提示用户键入一个参数(请注意,此脚本仅接受一个参数,如果用户输入包含零个或多个参数,则应报告警告/错误),检查输入参数是文件名还是目录名 1) 如果用户输入是文件,请在文件为空文件时退出,然后打印文件的最后一行 2) 如果用户输入的是目录,请在目录为空时退出,使用哈希表记录此目录中的文件名以及这些文件的评估期限(自上次评估文件以来的天数),在目录中查找最旧的文件(基于修改时间),并打印此文件的绝对路径。” 在过去的两天里,我一直在寻找有关如何使用File::Find的详细说明,但无法找到它。下面是我的代码,我想用File::Find替换-e$input部分,因为使用-e File操作符,我只能在当前目录中搜索,而不能搜索整个系统。我期待着您的回复,非常感谢您抽出时间如何在Perl中查找与提示输入匹配的文件而不使用-e和-d。。。文件::找到唯一的方法?,perl,file-find,Perl,File Find,下午好,朋友们 我被分配了以下任务,希望学习如何查看文件或目录是否存在 提示用户键入一个参数(请注意,此脚本仅接受一个参数,如果用户输入包含零个或多个参数,则应报告警告/错误),检查输入参数是文件名还是目录名 1) 如果用户输入是文件,请在文件为空文件时退出,然后打印文件的最后一行 2) 如果用户输入的是目录,请在目录为空时退出,使用哈希表记录此目录中的文件名以及这些文件的评估期限(自上次评估文件以来的天数),在目录中查找最旧的文件(基于修改时间),并打印此文件的绝对路径。” 在过去的两天里,我
#! /usr/bin/perl
# Assignment 9, check and read files and directories
use strict;
use warnings;
use Module1;
assnintro();
my @parameter;
my $input;
do { # This loop keeps calling pamcheck subroutine until the 1 param entered
# is a file in the directory, but I'd to expand the file test operator
# to all directories
$input = ();
@parameter = ();
pamcheck( \@parameter );
$input = $parameter[0];
if ( -e $input ) { } # Instead of simply checking current directory, I want to
# I want to see that the file exists in my system
else {
print color 'red';
print "The file or directory you entered, doesn't exist.\n";
print color 'reset';
}
} until ( -e $input );
if ( -d $input ) {
print "I am a directory.\n";
} else {
}
exit;
sub pamcheck { # This subroutine asks user to to enter a file or directory name
my ($parameter) = @_; # In the terminal, "parameters" are separated by space
my $elementcount; # Do elem ct. to make sure usr only entered 1 parameter
do {
@$parameter = ();
print "Enter one file or directory name: ";
@_ = split( /\s+/, <> ); # "Enter" key act as Ctrl D to avoid infinite
# param entry
push( @$parameter, @_ );
$elementcount = 0;
foreach (@_) {
$elementcount++;
}
if ( $elementcount != 1 ) { # Error msg if 1 param isn't entered
print color 'red';
print "Please enter only ONE parameter.\n";
print color 'reset';
} else {
}
} until ( $elementcount eq 1 ); # Loop continues until one param is entered
}
#/usr/bin/perl
#作业9,检查并读取文件和目录
严格使用;
使用警告;
使用模块1;
assnintro();
我的@参数;
我的$input;
do{#这个循环一直调用pamcheck子例程,直到输入1参数
#是目录中的一个文件,但我想展开file test操作符
#到所有目录
$input=();
@参数=();
pamcheck(\@参数);
$input=$parameter[0];
如果(-e$input){}#而不是简单地检查当前目录,我想
#我想查看该文件是否存在于我的系统中
否则{
打印颜色为“红色”;
打印“您输入的文件或目录不存在。\n”;
打印颜色“重置”;
}
}直至(-e$投入);
如果(-d$输入){
打印“我是一个目录。\n”;
}否则{
}
出口
sub pamcheck{#此子例程要求用户输入文件或目录名
my($parameter)=@#在终端中,“parameters”用空格分隔
my$elementcount;#Do elem ct.以确保usr只输入了1个参数
做{
@$parameter=();
打印“输入一个文件或目录名:”;
@_=split(/\s+/,);#“Enter”键作为Ctrl-D键,以避免出现无限大
#参数输入
推送(@$parameter,@u3;);
$elementcount=0;
foreach(foreach){
$elementcount++;
}
如果($elementcount!=1){#如果未输入1个参数,则返回错误消息
打印颜色为“红色”;
打印“请只输入一个参数。\n”;
打印颜色“重置”;
}否则{
}
}直到($elementcount eq 1)#循环继续,直到输入一个参数
}
文件::Find
不会做您认为它会做的事情。它基于Unixfind
命令,该命令遍历目录树。(并且可以对目录树中的所有文件执行某些操作)
您需要这样做的原因是,在一个有符号链接、挂载点等的世界中,深入遍历文件系统比您想象的要困难得多。因此,这是一个实用程序
File::Find
将允许您指定要在其上运行的代码块,例如,如果Find
,则指定每个文件
例如—
sub do_something {
print $File::Find::name,"\n";
}
find ( \&do_something, "." );
撇开这一点不谈——代码中有几点似乎表明您正朝着一个奇怪的方向前进
- 通过在标量上下文中测试数组,对数组中的元素进行计数要简单得多。 而不是: 对于(@array){ $elementcount++; }
my $elementcount = @array;
- 在空格上拆分
有点危险,因为它假定您没有包含空格的文件名。但现在让我们坚持下去STDIN
- 切勿将值分配给
。这是一个内置变量,弄乱它会以奇怪而可怕的方式破坏事物@
- 为什么要将“获取输入”封装到子例程中
use strict;
use warnings;
use File::Find;
sub find_matches {
my ( $search, $results_ref ) = @_;
if ( $_ eq $search ) {
push( @$results_ref, $File::Find::name );
}
}
while (<STDIN>) {
print "Please enter directory or file name:\n";
my @parameters = split(/\s+/); #split input in one or more whitespace.
#won't work if filename includes whitespace!
unless ( scalar @parameters == 1 ) {
print "Please enter only one value\n";
next;
}
my $search_text = pop @parameters;
my @results;
find( sub { \&find_matches( $search_text, \@results ) },
"/path/to/search" );
#now results has a list of all full paths to your files.
#because you traversed, you may well have duplicates.
if ( not @results ) {
print "No matches found\n";
}
foreach my $full_file_path (@results) {
if ( -d $full_file_path ) {
print "$full_file_path is a directory\n";
# do directory stuff;
last;
}
if ( -z $full_file_path ) {
print "$full_file_path is zero length\n";
}
}
last; #breaks you out the while loop - the 'next' above will skip this line
#if you don't have a valid parameter.
}
使用严格;
使用警告;
使用File::Find;
子查找匹配{
我的($search,$results\u ref)=@;
如果($\uEQ$搜索){
推送(@$results\u ref,$File::Find::name);
}
}
而(){
打印“请输入目录或文件名:\n”;
my@parameters=split(/\s+/)#将输入拆分为一个或多个空格。
#如果文件名包含空格,则不起作用!
除非(标量@参数==1){
打印“请只输入一个值\n”;
下一个
}
我的$search\u text=pop@参数;
我的@results;
查找(sub{\&find\u匹配($search\u text,\@results)},
“/path/to/search”);
#现在,results有一个指向文件的所有完整路径的列表。
#因为您已遍历,所以很可能有重复项。
如果(不是@results){
打印“未找到匹配项\n”;
}
foreach my$full_file_路径(@results){
如果(-d$full\u文件\u路径){
打印“$full_file_path是一个目录\n”;
#做目录工作;
最后;
}
如果(-z$full_文件_路径){
打印“$full\文件\路径长度为零\n”;
}
}
最后;#中断while循环-上面的“next”将跳过这一行
#如果没有有效的参数。
}
希望这能让你开始吗?所发生的事情是-您正在使用File::Find为文本字符串提供一个匹配列表,然后您可以逐一查看和处理该列表。请记住,如果你有直接的任务,你的任务规范不清楚你应该做什么