user1480041
user1480041

Reputation: 27

Checking a directory and matching with file

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

Answers (4)

Borodin
Borodin

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

PinkElephantsOnParade
PinkElephantsOnParade

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

TLP
TLP

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

Tanktalus
Tanktalus

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

Related Questions