如何在不使用-e和-d的情况下在Perl中查找与提示输入匹配的文件... File :: Find only way?

时间:2014-11-02 18:58:46

标签: perl file-find

下午好,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
}

1 个答案:

答案 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为您提供文本字符串的匹配列表,然后您可以单独进行处理。请记住,如果您的目录匹配的文件,您的作业规范不清楚应该怎么做,这就是为什么我不相信您需要进行遍历。