Perl目录是否过了if(!-d)语句? [readdir结果]

时间:2017-10-28 02:58:20

标签: perl if-statement directory

好的,所以我有一个基本上查看传入目录的程序,如果任何文件名与模式匹配,我将创建一个目录并将该特定文件和任何与之匹配的文件(无论扩展名)移动到该目录中。现在,如果他们不匹配,我应该将它们移到PassedInDir/misc/目录。

我在两种情况下都有条件避免传入任何目录(因为我的程序尚未准备好处理这些目录),例如if( ! -d $fp)

第一次在目录中运行时,一切正常。但是,当我在同一目录(现在应该只包含目录)上再次运行它时,我得到错误Could not move file assignmentZ to destination DataB/misc at projectSorter.pl line 16.。 AssignmentZ是一个目录,但在第二种情况下它以某种方式越过(!-d)

#!/usr/bin/perl -w
use File::Copy;
if(@ARGV < 1){
    print "\nUsage: proj6.pl <directory>\n\n";
    exit;
}
die("\nDirectory $ARGV[0] does not exist\n\n") if( ! -e $ARGV[0]);
opendir( DIR, $ARGV[0]) or die("\nCould not open directory $ARGV[0]\n\n");
while(($fp = readdir(DIR))){
    if($fp =~ m/proj(.*)\./){
        (! -d "$ARGV[0]/assignment$1") && (mkdir "$ARGV[0]/assignment$1");
        move("$ARGV[0]/$fp" , "$ARGV[0]/assignment$1") or die("Could not move file $fp to destination $ARGV[0]/assignment$1");
    }
    elsif(! -d $fp){  #gets past here!!!
        (! -d "$ARGV[0]/misc") && (mkdir "$ARGV[0]/misc");
        move("$ARGV[0]/$fp" , "$ARGV[0]/misc") or die("Could not move file $fp to destination $ARGV[0]/misc");
    }
}

这是唯一一个通过运行我的程序之前完成的目录。我很好奇为什么会这样。

2 个答案:

答案 0 :(得分:3)

$fp设置的

readdir与扫描目录相关。 chdir到扫描的目录或在-d测试前添加扫描的目录名称。

使用"$ARGV[0]/$fp"作为移动函数的参数。

perldoc -f readdir

  readdir DIRHANDLE
              返回由打开的目录的下一个目录条目               &#34;执行opendir&#34 ;. [...]
              如果您计划对a中的返回值进行文件测试               &#34; readdir&#34;,你最好在前面有问题的目录。               否则,因为我们没有&#34; chdir&#34;它本来就是               测试错误的文件。

答案 1 :(得分:0)

一些建议。

‣不要在Perl中使用-w标志。有些模块会关闭警告来完成工作,但-w标志是全局的。有了它,他们将报告应该被忽略的警告。

‣始终在每个脚本的顶部都有这两行。

use strict;
use warnings;

这些会在代码中发现很多错误。有关详细信息,请参阅perldoc strictperldoc warnings

‣使用glob()Find::Find代替opendir / readdir / closedir。

‣使用File::Path中的make_path()代替mkdir

‣使用if语句进行条件执行,而不是&&

‣在代码中放置空行以便于阅读。

File::FindFile::path是与Perl一起安装的标准模块。有关标准模块的列表,请参阅perldoc perlmodlib

#!/usr/bin/perl

# --------------------------------------
# pragmas

use strict;
use warnings;

# --------------------------------------
# modules
use File::Copy;
use File::Path   qw( make_path );

# --------------------------------------
# main

# make sure there is something to work on
if(@ARGV < 1){
    print "\nUsage: proj6.pl <directory>\n\n";
    exit;
}

# arguments should be directories
for my $src_dir ( @ARGV ){

    # validate the source directory
    die("\n$src_dir does not exist\n\n")     if( ! -e $src_dir);
    die("\n$src_dir is not a directory\n\n") if( ! -d $src_dir);

    # move proj* files
    for my $proj ( glob( "$src_dir/proj*" )){

        # get the proj number
        ( my $number ) = $proj =~ m/proj(.*)\./;

        # get the destination directory
        my $dst_dir = "$src_dir/assignment$number";

        # create the directory where it goes
        if( ! -d $dst_dir ){
            make_path( $dst_dir ) or die "could not make path $dst_dir";
        }

        # move the file
        move( $proj, $dst_dir ) or die( "could not move file $proj to destination $dst_dir" );

    } # end of $proj files

    # move other files
    for my $file ( grep { ! -d } glob( "$src_dir/*" )){

        # get the destination directory
        my $dst_dir = "$src_dir/misc";

        # create the directory where it goes
        if( ! -d $dst_dir ){
            make_path( $dst_dir ) or die "could not make path $dst_dir";
        }

        # move the file
        move( $file, $dst_dir ) or die( "could not move file $file to destination $dst_dir" );

    } # end other files

} # end of src_dir