检查目录并与文件匹配
我想查看名为missing
的文件,然后查看名为flags
的目录。检查目录并与文件匹配
missing
中列出的每个文件将始终出现在flags
目录中。
我想查看flags
目录中的每个文件,然后查看它们是否在missing
文件中。如果其中一个不是,请从flags
目录中删除该文件。
@flags=`ls $dir`;
$flags_size = scalar @flags;
$file = "/home1/t01jkxj/check_st/missing";
$filesize = -s $file;
if ($filesize < $flags_size) {
##What to do??##
}
检查散列。将所有缺少的条目放入散列中。然后遍历标志目录中的所有文件并检查它是否在散列中。如果是,很好,如果没有,删除文件。
my %missings = map { chomp; $_ => 1 } do {
open my $fh, '<', $missing_file or die "Can't read $missing_file: $!";
<$fh>
};
opendir my $dh, $dir or die "Can't read from $dir: $!";
while(readdir $dh) {
unlink $_ unless delete $missings{$_};
}
# I know, you said this can't happen.
if (keys %missings) {
print "The following are in $missing_file but not in $dir:\n";
print " $_\n" for sort keys %missings;
}
警告:完全未经测试。我在网页浏览器中输入了这个框。
您的警告是有保证的。你的代码将试图解除链接'.'和'..'(但它有可能失败,因为unlink通常不能删除目录),并且在错误的目录中。 – TLP
现在不在Linux中,但这是您需要做的事情。该脚本收集文件和阵列目录中的文件列表,然后找出两者的区别。我会测试,但不能真的) - =。考虑它伪代码!:
use strict;
use warnings;
my $fi;
my $line;
my @to_delete;
my $var;
my @indir;
my @files;
# the difference of @females and @simpsons
@indir = `ls`;
open($fi, "< list.txt");
while ($line = <$fi>)
{
chomp($line);
push @files, $line;
}
@to_delete=grep(!defined $indir{$_}, @files); #gets difference of the two arrays
print "Delete this:\t$_\n" foreach (@to_delete);
你不能像这样使用chomp:'push @files,chomp($ line)'。 'chomp'返回从参数中移除的字符总数,而不是参数本身。而且,你不能像这样grep,因为你在'%flags'哈希中没有任何键。 – TLP
谢谢 - 这些都是我的巨大错误。让我认识其他人。或者只是编辑它是正确的,因为我可能会花太多的草稿。 – PinkElephantsOnParade
在我看来,你可以用bash命令来做到这一点。例如:
cd /path/to/flags; ls | grep -vf missing.txt | xargs rm
注意:请不要在没有测试的情况下运行上述操作。
在perl中,在代码中稍微详细一点并发出警告可能是一个好主意。当然,这些警告可以被移除以用于自动化作业。
use strict;
use warnings;
my $dir = "/path/to/flags";
chdir $dir or die $!; # change working directory
my @flags = <*>; # get a list of the files
my $file = "/home1/t01jkxj/check_st/missing";
open my $fh, "<", $file or die $!;
chomp(my @missing = <$fh>); # get file names and remove newlines
my %missing = map { $_ => 1 } @missing; # ..and put them in a hash
my @delete;
for my $file (@flags) { # all files not in the hash go into @delete
push @delete, $file unless $missing{$file};
}
if (@delete) { # do not delete without confirmation
print @delete . " files to delete\[email protected]\n---\nDelete them all? ";
my $reply = <>;
if ($reply =~ /^y$/) {
unlink $_ or warn "$_: $!" for @delete;
}
} else {
print "No missing files to delete.\n";
}
你不描绘这一missing
文件的格式,但我想它每行包含一个文件中并赋予该文件的完整绝对路径。如果我猜错了,你需要调整这个解决方案。
该程序将missing
文件加载到散列中。每个散列元素都有文件名作为其键值,值为1.
打开flags
目录,并将路径添加到每个文件名中以形成$filename
中的绝对路径。如果它没有出现在%missing
散列中,则会打印该文件名。要实际删除该文件,unlink
行应该被取消注释。
use strict;
use warnings;
my $missing = "/home1/t01jkxj/check_st/missing";
open my $fh, '<', $missing or die qq(Unable to open "$missing" for read: $!);
my %missing;
while (<$fh>) {
next unless /\S/;
chomp;
$missing{$_} = 1;
}
my $dir = '/path/to/flags';
opendir my $dh, $dir or die qq(Unable to open directory "$dir": $!);
for my $file (readdir $dh) {
my $filename = "$dir/$file";
unless ($missing{$filename}) {
# unlink $filename;
print qq(File "$filename" deleted as not found in 'missing' file\n);
}
}
为什么要将'$ file'的大小与'@ flags'数组中的元素数进行比较? – TLP
@TLP:我认为你很清楚OP不理解'-s'运算符。 – Borodin
所以你想删除名为'flags'的目录中的所有文件,这些文件不会出现在名为'missing'的文件中? – Borodin