mil*_*bos 1 arrays perl grep text-processing
我想捕获 中的文件CWD和 中的文件之间的差异@files:
#!/usr/bin/perl -w
use Cwd qw[getcwd abs_path];
opendir CWD, getcwd;
@files=grep{!/^\./}readdir CWD;
push @files, ("foo.txt", "bar.txt");
for my $i (@files){
@difference=grep { !/^\./ and $i!=$_ } readdir CWD;
}
print "$_\n" for @differenc
Run Code Online (Sandbox Code Playgroud)
现在当前目录有这个文件:
$ls
a.txt e.txt getopt.html
Run Code Online (Sandbox Code Playgroud)
使用这个表达式push @files, ("foo.txt", "bar.txt");
,数组有这些元素:("foo.txt", "bar.txt", "a.txt", "e.txt", "getopt.html"),这是正确的,但现在我只想选择那些不在CWD: 中的文件
@difference=grep { !/^\./ and $i!=$_ } readdir CWD;,所以我希望数组@difference再次("foo.txt", "bar.txt")只有(我现在这没有意义,它是例如)。但是打印出来什么都不输出,怎么回事?
您的代码有很多问题:
您的第二个readdir(在for my $i (@files)循环中)没有读取任何内容,因为第一个 ( @files=grep{!/^\./}readdir CWD;) 已经读取了整个目录。您可以rewinddir先使用,但简单地使用@files(在推送foo.txt和之前bar.txt)的副本会更简单、更有效。
您正在使用!=而不是ne比较字符串。
循环的每次迭代都会擦除之前的值,@differences因为您用=. 想必push会更有意义。
循环内部的逻辑有点缺陷。grep返回满足条件的元素,但您更感兴趣的是是否有任何元素满足它。
您应该检查是否opendir成功(通过添加or die ...到opendir线)。另请注意,这open my $CWD, getcwd等效于更简单的open my $CWD, ".".
您可能想要做的是:
use strict;
use warnings;
opendir my $CWD, "." or die "Could not open '.': $!";
my @files = grep{!/^\./} readdir $CWD;
my @init_files = @files;
push @files, ("foo.txt", "bar.txt");
my @difference;
for my $i (@files){
push @difference, (grep { !/^\./ and $i eq $_ } @init_files) ? () : $i;
}
print "$_\n" for @difference
Run Code Online (Sandbox Code Playgroud)
然而,这远非有效,而且比它需要的更复杂。我建议改为:
my %files = map { $_ => 1 } grep {!/^\./} readdir $CWD;
my @difference;
for ("foo.txt", "bar.txt") {
push @difference, $_ if ! exists $files{$_};
}
print "$_\n" for @difference
Run Code Online (Sandbox Code Playgroud)
请注意,我已添加use strict; use warnings;到脚本中。始终将它们添加到您的代码中。虽然在这种特定情况下,它不会帮助您找出问题所在,但它会在未来为您节省无数时间。此外,始终使用词法文件/目录句柄(即,使用 doopendir my $CWD, "dir"而不是open CWD, "dir")。
| 归档时间: |
|
| 查看次数: |
83 次 |
| 最近记录: |