Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
数据驱动的perl脚本_Perl - Fatal编程技术网

数据驱动的perl脚本

数据驱动的perl脚本,perl,Perl,我想列出目录中的文件n文件夹。以下是此目录中的文件列表 Output1.sv Output2.sv Folder1 Folder2 file_a file_b file_c.sv 但其中一些,我不想被列出来。未包含文件的列表,我在input.txt中列出,如下所示。注意:有些是文件,有些是文件夹 NOT_INCLUDED=file_a NOT_INCLUDED=file_b NOT_INCLUDED=file_c.sv 这是代码 #!/usr/intel/perl use strict;

我想列出目录中的文件n文件夹。以下是此目录中的文件列表

Output1.sv
Output2.sv
Folder1
Folder2
file_a
file_b
file_c.sv
但其中一些,我不想被列出来。未包含文件的列表,我在input.txt中列出,如下所示。注意:有些是文件,有些是文件夹

NOT_INCLUDED=file_a
NOT_INCLUDED=file_b
NOT_INCLUDED=file_c.sv
这是代码

#!/usr/intel/perl

use strict;
use warnings;

my $input_file    = "INPUT.txt";

open ( OUTPUT, ">OUTPUT.txt" );

file_in_directory();

close OUTPUT;


sub file_in_directory {

   my $path       = "experiment/";

   my @unsort_output;
   my @not_included;
   open ( INFILE, "<", $input_file);
   while (<INFILE>){
      if ( $_ =~ /NOT_INCLUDED/){
          my @file = $_;
          foreach my $file (@file) {
              $file =~ s/NOT_INCLUDED=//;
              push @not_included, $file;
          }
      }
   }
   close INFILE;

   opendir ( DIR, $path ) || die "Error in opening dir $path\n";
   while ( my $filelist = readdir (DIR) ) {
      chomp $filelist;
      next if ( $filelist =~ m/\.list$/ );
      next if ( $filelist =~ m/\.swp$/ );
      next if ( $filelist =~ s/\.//g);
      foreach $_ (@not_included){
         chomp $_;
         my $not_included = "$_";
         if ( $filelist eq $not_included ){
            next;
         }

      push @unsort_output, $filelist;         
    }

   closedir(DIR);

   my @output = sort @unsort_output;
   print OUTPUT @output;   
}

但是我得到的输出似乎仍然包含那个不需要的文件。

这部分代码毫无意义:

   while ( my $filelist = readdir (DIR) ) {
      ...
      foreach $_ (@not_included){
         chomp $_;
         my $not_included = "$_";
         if ( $filelist eq $not_included ){
            next;
         }  # (1)

      push @unsort_output, $filelist;  # (2)
    }
此代码包含三个大括号(
{
),但只有两个大括号(
}
)。如果您尝试按原样运行代码,它将失败并出现语法错误

push
行(标记为
(2)
)是
foreach
循环的一部分,但缩进时就好像它在外部一样。要么它应该缩进更多(与
(1)
对齐),要么你需要在它前面添加一个
}
。这两种选择都没有多大意义:

  • 如果
    push
    foreach
    循环之外,则
    next
    语句(以及整个
    foreach
    循环)无效。它可以被删除
  • 如果
    push
    位于
    foreach
    循环内,则每个目录条目(
    $filelist
    )都将被推送多次,在
    @not_included
    中,每行推送一次(在
    @not_included
    中列出的名称除外;这些名称将被推送一次)
还有其他几个问题。例如:

  • $filelist=~s/\.//g
    删除文件名中的所有点,例如将
    文件\u c.sv
    转换为
    文件\u csv
    。这意味着它永远不会匹配输入文件中的
    NOT_INCLUDED=file_c.sv
  • 更糟糕的是,
    下一个if s//
    部分意味着循环跳过名称包含点的所有文件,例如
    Output1.sv
    Output2.sv
  • 打印结果时不使用分隔符,因此您将得到如下结果
    OUTPUT.txt中的
    Folder1Folder1Folder1Folder2Folder2Folder2file\u afile\u afile\u bfile\u b
  • 全局变量是无理由使用的,例如
    infle
    DIR
下面是我将如何构造代码:

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

my $input_file = 'INPUT.txt';

my %is_blacklisted;
{
    open my $fh, '<', $input_file or die "$0: $input_file: $!\n";
    while (my $line = readline $fh) {
        chomp $line;
        if ($line =~ s!\ANOT_INCLUDED=!!) {
            $is_blacklisted{$line} = 1;
        }
    }
}

my $path = 'experiment';

my @results;
{
    opendir my $dh, $path or die "$0: $path: $!\n";
    while (my $entry = readdir $dh) {
        next
            if $entry eq '.' || $entry eq '..'
            || $entry =~ /\.list\z/
            || $entry =~ /\.swp\z/
            || $is_blacklisted{$entry};

        push @results, $entry;
    }
}

@results = sort @results;

my $output_file = 'OUTPUT.txt';
{
    open my $fh, '>', $output_file or die "$0: $output_file: $!\n";
    for my $result (@results) {
        print $fh "$result\n";
    }
}
#/usr/intel/perl
严格使用;
使用警告;
我的$input_文件='input.txt';
我的%被列入黑名单;
{
打开我的$fh、、$output_文件或死“$0:$output_文件:$!\n”;
对于我的$result(@results){
打印$fh“$result\n”;
}
}
INPUT.txt的内容(更具体地说,是
未包含=
之后的部分)被读入哈希(
%被列入黑名单)。这允许轻松查找条目

然后我们处理目录条目。我们跳过
(我想您不需要这些)以及所有以
*结尾的文件。列出
*.swp
(这是您的原始代码)。我们还跳过任何被列入黑名单的文件,即在
INPUT.txt
中被指定为排除在外的文件。其余条目收集在
@results


我们对结果进行排序,并将它们写入
OUTPUT.txt
,每行一个条目。

不要与您的代码偏离太多,下面是解决方案。请查看以下评论:

#!/usr/intel/perl
use strict;
use warnings;
my $input_file    = "INPUT.txt";
open ( OUTPUT, ">OUTPUT.txt" );
file_in_directory();
close OUTPUT;

sub file_in_directory {
    my $path       = "experiment/";
    my @unsort_output;
    my %not_included; # creating hash map insted of array for cleaner and faster implementaion.
    open ( INFILE, "<", $input_file);
    while (my $file = <INFILE>) {
        if ($file =~ /NOT_INCLUDED/) {
            $file =~ s/NOT_INCLUDED=//;
            $not_included{$file}++; # create a quick hash map of (filename => 1, filename2 => 1)
        }
    }
    close INFILE;
    opendir ( DIR, $path ) || die "Error in opening dir $path\n";
    while ( my $filelist = readdir (DIR) ) {
        next if $filelist =~ /^\.\.?$/xms; # discard . and .. files
        chomp $filelist;
        next if ( $filelist =~ m/\.list$/ );
        next if ( $filelist =~ m/\.swp$/ );
        next if ( $filelist =~ s/\.//g);
        if (defined $not_included{$filelist}) {
            next;
        }
        else {
            push @unsort_output, $filelist;
        }
    }
    closedir(DIR);  # earlier the closedir was inside of while loop. Which is wrong.
    my @output = sort @unsort_output;
    print OUTPUT join "\n", @output;
}
#/usr/intel/perl
严格使用;
使用警告;
my$input\u file=“input.txt”;
打开(输出,“>OUTPUT.txt”);
_目录()中的文件_;
闭合输出;
\u目录中的子文件\u{
我的$path=“实验/”;
我的@unsort_输出;
我的%not#u include;#创建哈希映射而不是数组,以便更干净、更快地实现。

open(infle),“如果你有input.txt文件的例子,问题会更清楚。另外:`my@file=$\uu;foreach my$file(@file){`。不清楚为什么@file是一个数组。hi@SachinDangol是我上面提到的input.txt文件。我存储在数组中,因为它有一个“NOT\u”列表“与input.txt中的一样,
$\
是单个值。
my@file=$\
只创建一个元素数组,即
$file[0]
将等于
$
。在这里使用数组没有任何意义。代码中存在许多问题,但最重要的是它甚至无法编译:
在.code.tio行53行末尾的
/^.\.\?$/xms
匹配的不仅仅是
。它匹配任何文件名只要包含一行
就可以了。为什么要添加
/m
标志?
chomp$filelist
毫无意义。它是一个目录项,不是一行。
join“\n”,@output
保留最后一行未终止。如果不需要花费任何成本来修复问题,为什么要创建断开的文本文件?
打印输出映射“$\un”,@output;
不再或更难键入(或者在非古代Perl中,
说@output;
)在测试哈希键是否存在时,
exists
是比
defined
更好的选择。
#!/usr/intel/perl
use strict;
use warnings;
my $input_file    = "INPUT.txt";
open ( OUTPUT, ">OUTPUT.txt" );
file_in_directory();
close OUTPUT;

sub file_in_directory {
    my $path       = "experiment/";
    my @unsort_output;
    my %not_included; # creating hash map insted of array for cleaner and faster implementaion.
    open ( INFILE, "<", $input_file);
    while (my $file = <INFILE>) {
        if ($file =~ /NOT_INCLUDED/) {
            $file =~ s/NOT_INCLUDED=//;
            $not_included{$file}++; # create a quick hash map of (filename => 1, filename2 => 1)
        }
    }
    close INFILE;
    opendir ( DIR, $path ) || die "Error in opening dir $path\n";
    while ( my $filelist = readdir (DIR) ) {
        next if $filelist =~ /^\.\.?$/xms; # discard . and .. files
        chomp $filelist;
        next if ( $filelist =~ m/\.list$/ );
        next if ( $filelist =~ m/\.swp$/ );
        next if ( $filelist =~ s/\.//g);
        if (defined $not_included{$filelist}) {
            next;
        }
        else {
            push @unsort_output, $filelist;
        }
    }
    closedir(DIR);  # earlier the closedir was inside of while loop. Which is wrong.
    my @output = sort @unsort_output;
    print OUTPUT join "\n", @output;
}