检查目录并与文件匹配

问题描述:

我想查看名为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??## 
    } 
+0

为什么要将'$ file'的大小与'@ flags'数组中的元素数进行比较? – TLP

+0

@TLP:我认为你很清楚OP不理解'-s'运算符。 – Borodin

+0

所以你想删除名为'flags'的目录中的所有文件,这些文件不会出现在名为'missing'的文件中? – Borodin

检查散列。将所有缺少的条目放入散列中。然后遍历标志目录中的所有文件并检查它是否在散列中。如果是,很好,如果没有,删除文件。

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; 
} 

警告:完全未经测试。我在网页浏览器中输入了这个框。

+0

您的警告是有保证的。你的代码将试图解除链接'.'和'..'(但它有可能失败,因为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); 
+0

你不能像这样使用chomp:'push @files,chomp($ line)'。 'chomp'返回从参数中移除的字符总数,而不是参数本身。而且,你不能像这样grep,因为你在'%flags'哈希中没有任何键。 – TLP

+0

谢谢 - 这些都是我的巨大错误。让我认识其他人。或者只是编辑它是正确的,因为我可能会花太多的草稿。 – 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); 
    } 
}