Reputation: 27
I want to look at a file called missing
and then look within a directory called flags
.
Every file listed in missing
will always appear in the flags
directory.
I want to look at every file in the flags
directory and then see if they are in the missing
file. If one of them is not, delete that file from the flags
directory.
@flags=`ls $dir`;
$flags_size = scalar @flags;
$file = "/home1/t01jkxj/check_st/missing";
$filesize = -s $file;
if ($filesize < $flags_size) {
##What to do??##
}
Upvotes: 0
Views: 157
Reputation: 126762
You don't decribe the format of the missing
file, but I guess it contains one file per line and gives the full absolute path to the files. You will need to adjust this solution if I have guessed incorrectly.
This program loads the missing
file into a hash. Each hash element has the filename as its key and a value of 1.
The flags
directory is opened, and the path is added to each of the file names to form an absolute path in $filename
. The filename is printed if it doesn't appear in the %missing
hash. To actually delete the file the unlink
line should be uncommented.
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);
}
}
Upvotes: 1
Reputation: 6592
Not in Linux right now but this is sort of what you need to do. This script collects the listing of files in the file and in the array directory, then finds the difference of the two. I would test but can't really )-=. Consider it pseudocode!:
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);
Upvotes: 0
Reputation: 67920
Seems to me that you can do this with a bash command too. Something like:
cd /path/to/flags; ls | grep -vf missing.txt | xargs rm
NOTE: Please don't run the above without testing it.
In perl, it would probably be a good idea to be somewhat verbose in the code and issue a warning. Of course, the warnings can be removed for automated jobs.
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\n@delete\n---\nDelete them all? ";
my $reply = <>;
if ($reply =~ /^y$/) {
unlink $_ or warn "$_: $!" for @delete;
}
} else {
print "No missing files to delete.\n";
}
Upvotes: 0
Reputation: 22294
Check out hashes. Put all your entries from missing into a hash. Then loop through all the files in the flags dir and check if it's in the hash. If it is, fine, if not, delete the file.
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;
}
Warning: completely untested. I typed this right into the box in my web browser.
Upvotes: 0