forro has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks!

Task: I have a .txt file with filenames which have to be deleted. I need to read the file, append the ".png" and ".txt" extension to the filenames. Then, I need to search for those files on my system, print out the full paths and in the end, to delete the files. This is what I got until now:

#!/usr/bin/perl use strict; use warnings; use File::Find; print "Files to be deleted: \n"; open ("file", "remove.txt") || die ("Could not open file. \n $!"); @text=<file>; print(@text); close("file"); my $dir = "/Downloads/png_files/"; find(\&wanted, $dir); sub wanted { print $File::Find::name if -d };

Problem: I tried, but failed, in appending the extensions to the filenames in my .txt file and I also do not know how to pass the values stored in the array to the find () subroutine, the "if" clause.

I just started learning Perl and it's a bit out of my reach. If anyone can lend a helping hand, I would appreciate it.

Thank you!

Replies are listed 'Best First'.
Re: Read .txt file -> append extension -> find on disc -> delete
by Perlbotics (Archbishop) on Oct 27, 2012 at 12:35 UTC

    Hi forro and welcome to the Monastery.

    Here are some hints to get you going:

    First correct the errors use strict; is giving you. Hint: my.

    Do not forget to chomp( @text ); otherwise you could end up searching for somefileame\n.png which most likely does not exist.

    Put the filenames from @text into a hash %files_to_find for easy lookup by using a for-loop or map. Decide if you want to create hash-entries for the filename only or for the two variations (filename.txt, filename.png). Creating hash-entries for both names (as keys) makes the wanted()-sub less complex but uses more memory. However, memory-consumption is most likely not an issue here unless you have several hundreds of million files in your remove.txt.

    In the wanted()-sub, check if $files_to_find{$filename} exists. Whether $filename is $_ (the filename w/o directory) or $File::Find::name depends on the format of the entries in remove.txt - i.e. if the entries are basenames or also include the full path. You should also check if the file in question is a regular file (-f).
    If a match has been found, put the abs. filename in a @remove_these_files list for review and removal in a later step.

    Remove files from @remove_these_files after the FF-search. Make a backup and just print out what would have been removed before fiddling around with unlink.

    Minor nitpick: The open() doesn't look right. Try open( my $file, '<', "remove.txt") or ..... Then read from <$file>. What you do works, but you create a file-handle file that's visible throughout your program. Usually not a good idea, but IMO tolerable for a small script. It might just be a good idea to get into the 3-args-open-habit early.

Re: Read .txt file -> append extension -> find on disc -> delete
by Anonymous Monk on Oct 27, 2012 at 10:15 UTC

    I just started learning Perl and it's a bit out of my reach. If anyone can lend a helping hand, I would appreciate it.

    perlintro gives a quick leg-up, as does http://perl-tutorial.org/

Re: Read .txt file -> append extension -> find on disc -> delete
by Anonymous Monk on Oct 27, 2012 at 10:25 UTC

    Problem: I tried, but failed, in appending the extensions to the filenames in my .txt file

    You should show that too :)

    and I also do not know how to pass the values stored in the array to the find () subroutine, the "if" clause.

    File::Find#SYNOPSIS gives examples