如何遍历linux中的子目录并查找没有" .csv"的文件在linux上使用perl的扩展

时间:2015-07-06 16:56:31

标签: perl csv

#!/usr/bin/perl

my $dir = '/path/to/dir';
open( DIR, $dir ) or die $!;
while ( my $file = readdir(DIR) ) {
    next if ( $file =~ m/(^\.)/ );
    if ( $file !~ m/csv$/ ) {
        print "*** renaming file $file ***\n";
        $oldfile = $file;
        $file =~ s/\..*$/.csv/;
        print "$oldfile => $file\n";
        rename $oldfile, $file;
        print "Done\n";
    }
}

我试过perl -c来查看是否存在语法错误。我想某种方式我在逻辑上有一个缺陷。感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

你有几个问题

  • 您正在使用open来阅读目录而不是opendir

  • 您正在处理readdir返回

  • 的文件和目录
  • 您正在重命名没有路径的文件名,这意味着Perl会查看当前目录,该目录可能不是/path/to/dir

这将完成您的预期

use strict;
use warnings;

my $dir = '/path/to/dir';

chdir $dir or die $!;
opendir my $dh, '.' or die $!;

while ( my $file = readdir $dh ) {

    next unless -f $file;
    next if $file =~ /\.csv\z/i;

    print "*** Renaming file $file ***\n";

    my $newfile = $file;
    $newfile =~ s/\.[^.]*\z//;
    $newfile .= '.csv';

    print "$file => $newfile\n";
    rename $file, $newfile or die $!;
    print "Done\n";
}

答案 1 :(得分:0)

首先,open()用于文件。你想要的是opendir()。接下来,当您使用opendir(), readdir()时,它不会保留路径信息,因此您需要将其添加到您重命名的文件中。第三,使用词法句柄而不是裸名称更常见。最后,始终use strict;use warnings;会直接指出您的问题。

以下是您的代码的略微更新版本:

#!/usr/bin/perl
use warnings;
use strict;

my $dir = "/path/to/dir";
opendir(my $dh, $dir) or die $!;

while ( my $file = readdir($dh) ) {
    next if ( $file =~ m/(^\.)/ );
    next unless -f $file;
    if ( $file !~ m/csv$/ ) {
        print "*** renaming file $file ***\n";
        my $oldfile = $file;
        $file =~ s/\..*$/.csv/;
        print "$oldfile => $file\n";
        rename "$dir/$oldfile", "$dir/$file";
        print "Done\n";
    }
}

另一种方法是使用文件glob(根据Sobrique的建议):

#!/usr/bin/perl
use warnings;
use strict;

my @files = </path/to/dir/*>;

for my $file (@files){

    next unless -f $file;

    if ($file !~ /\.csv$/){
        print "*** renaming file $file ***\n";
        my $oldfile = $file;
        $file =~ s/\..*$/.csv/;
        print "$oldfile => $file\n";
        rename $oldfile, $file;
        print "Done!\n";
    }
}