下午好,stackoverflow朋友们!
我已获得以下作业,并希望了解如何查看文件或目录是否存在。
“提示用户键入一个参数(请注意,此脚本只接受一个参数,如果用户输入包含零个或多个参数,则应报告警告/错误),检查输入参数是文件名还是目录名。
1)如果用户输入是文件,则在文件为空文件时退出,并打印文件的最后一行。
2)如果用户输入是目录,则在目录为空时退出,使用哈希表记录此目录中的文件名以及这些文件的评估年龄(自上次评估文件以来的天数) ,找到目录中最旧的文件(基于修改时间),并打印该文件的绝对路径。“
我花了最近两天的时间查看如何使用File :: Find的详细说明,但不能。下面是我的代码,我想用File :: Find替换-e $输入节,因为使用-e文件操作符,我只能搜索当前目录而不是整个系统。我期待着您的回复,非常感谢您的时间。
#! /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
}
答案 0 :(得分:0)
File::Find
并不能按照您的想法行事。它基于遍历目录树的Unix find
命令。 (并且可以对目录树中的所有文件执行操作)。
你需要这个的原因是,在一个有符号链接,挂载点等的世界中,你想要对文件系统进行深度遍历比你想象的更难。因此这是一个实用程序。
File::Find
允许您执行的操作是指定要在其上运行的一大块代码。每个文件find
。
作为一个例子 -
sub do_something {
print $File::Find::name,"\n";
}
find ( \&do_something, "." );
除此之外 - 您的代码中有几件事情似乎暗示您会朝着奇怪的方向前进。
计算数组中的元素要简单得多。 而不是:
for(@array){ $ elementCount中++; }
你可以这样做:
my $elementcount = @array;
在空格上分割STDIN
有点冒险,因为它假设你没有带空格的文件名。但是现在让我们坚持下去。
永远不要将值分配给@_
。这是一个内置的变量,弄乱它可以以奇怪和可怕的方式破坏事物。
为什么要封装“获取输入”&#39;进入子程序?
无论如何 - 假设您需要遍历文件系统以查找目录/文件:
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为您提供文本字符串的匹配列表,然后您可以单独进行处理。请记住,如果您的目录和匹配的文件,您的作业规范不清楚应该怎么做,这就是为什么我不相信您需要进行遍历。