Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Delete files using existing list

0 views
Skip to first unread message

Fr...@pleasenospam.com

unread,
Feb 26, 2002, 8:01:32 PM2/26/02
to
Hello there,

I generate a list of the files in C:\WIN\TEMP with the Perl script below
(Win98SE).
I then use the list (H:\filelist.txt) to delete files in C:\WinTemp,
using a Winbatch-scriptfile during start-up. This works fine but is slow
and not very elegant.
Can anybody please show me how to delete the files in the list within
the Perl script?

#!/usr/local/bin/perl -w
use strict;
my $outfile = 'H:\filelist.txt' ;
open(STDOUT, "> $outfile")
or die "Could not open targetfile for writing: $!\n";

use File::Find;
my @list;
find sub {
push @list, [$File::Find::name, (stat _)[4]]
if -M > 1;
}, 'C:\WIN\TEMP';

for (@list) {
printf "%10s %s\n", $_->[0] ;
}
close(STDOUT) or die "could not close STDOUT: $!";

--- Fred

Jon Ericson

unread,
Feb 26, 2002, 8:27:02 PM2/26/02
to
Fr...@PleaseNoSpam.com writes:

> Can anybody please show me how to delete the files in the list
> within the Perl script?

perldoc -f unlink

Jon
--
Two are better than one, because they have a good return for their
work: If one falls down, his friend can help him up... Though one
may be overpowered, two can defend themselves. A cord of three
strands is not quickly broken. -- Ecclesiastes 4:9,12 (NIV)

Godzilla!

unread,
Feb 26, 2002, 11:13:20 PM2/26/02
to
Fr...@PleaseNoSpam.com wrote:

(snipped)

> I generate a list of the files in C:\WIN\TEMP with the Perl script below

> Can anybody please show me how to delete the files in the list within


> the Perl script?

> #!/usr/local/bin/perl -w
> use strict;

There is no need for pragma, warnings and strict,
in your final script version. Those only serve
to slow down your script and bloat memory usage.


> push @list, [$File::Find::name, (stat _)[4]]
> if -M > 1;

You have a logic problem here. Currently you are
pushing both parent directory / child directories
and files into your array.

You only want file names and their associated path.

Add a logical AND operator, which tests for a file,
to your syntax as such:

if -M > 1 && -f;

Complete example:

push @list, [$File::Find::name, (stat _)[4]]

if -M > 1 && -f;

This will parse File Find returns leaving only files and paths
with no directories nor child directories. This will prepare
your method for deleting files but not directories.


You may find this quicker and certainly easier. Instead
of creating your list of files, filelist.txt, simply
delete your files directly by not creating this list
initially. Easy enough, remove your open Standard Output
syntax, open (STDOUT ... etc), and replace your print
with this syntax:

for (@list)
{ unlink ($_->[0]); }

Complete example:

#!/usr/local/bin/perl



use File::Find;
my @list;
find sub

{ push @list, [$File::Find::name, (stat _)[4]] if -M > 1 && -f; },
'C:\WIN\TEMP';

for (@list)
{ unlink ($_->[0]); }

exit;


Your alternative is to retain creation of your filelist.txt
and later looping through it deleting files as you go. You
can create an array from filelist.txt or while loop each
line. If you do this, remember to chomp off newline \n
characters for each entry for a correct path, if you
print newlines to your file.

unlink () is your easiest choice for deleting files.


Incidently you may use left slashes or right slashes for
your file paths, under Perl for Win32.

c:\some\path\to\a\file

c:/some/path/to/a/file

You will be well advised there are a small handful of
Perl functions which will croak if left slashes are used.
It is a good habit to simply use right slashes.

Double check your C:\WIN\TEMP path. It should be,

C:\WINDOWS\TEMP


Are you sure you want to blindly delete all files in
your windows/temp directory and sub-directories?

Usually this is safe but not always.


Godzilla!

Chris Eustace

unread,
Feb 27, 2002, 12:02:48 AM2/27/02
to
<Fr...@PleaseNoSpam.com> wrote in message news:3C7C2FFC...@home.com...

[snipped]

>
> #!/usr/local/bin/perl -w
> use strict;
> my $outfile = 'H:\filelist.txt' ;
> open(STDOUT, "> $outfile")
> or die "Could not open targetfile for writing: $!\n";
>
> use File::Find;
> my @list;
> find sub {
> push @list, [$File::Find::name, (stat _)[4]]
> if -M > 1;
> }, 'C:\WIN\TEMP';
>
> for (@list) {
> printf "%10s %s\n", $_->[0] ;

A copy and paste error? Two string control specifications, but just one
string passed in!!??
In any case, 'unlink' is the function you want.

unlink $_->[0];

Martien Verbruggen

unread,
Feb 27, 2002, 12:16:31 AM2/27/02
to
On Tue, 26 Feb 2002 20:13:20 -0800,
Godzilla! <godz...@stomp.stomp.tokyo> wrote:
> Fr...@PleaseNoSpam.com wrote:
>
> (snipped)
>
>> I generate a list of the files in C:\WIN\TEMP with the Perl script below
>
>> Can anybody please show me how to delete the files in the list within
>> the Perl script?
>
>> #!/usr/local/bin/perl -w
>> use strict;
>
> There is no need for pragma, warnings and strict,
> in your final script version. Those only serve
> to slow down your script and bloat memory usage.

Nonsense. It is _always_ a good idea to use strict and warning is a
Perl program, unless you know why you don't want or need it. If there
is a measurable performance penalty for either strict or -w (and I
doubt that there is), it is insignificant compared to all the other
things perl has to do when starting, compiling a program, and
executing it. The only reason Godzilla is saying this, is because it
knows that someone will have to post a reply to correct that piece of
crappy misinformation. Godzilla, being a troll, thrives on that sort
of thing.

Do not pay any attention to what Godzilla says. It is a troll, and
has no decent working knowledge of Perl or programming in general.
Search groups.google.com to see a history of its posts and replies
to these posts.

Martien
--
|
Martien Verbruggen | The gene pool could use a little
Trading Post Australia Pty Ltd | chlorine.
|

Chris Eustace

unread,
Feb 27, 2002, 12:21:42 AM2/27/02
to
<Fr...@PleaseNoSpam.com> wrote in message news:3C7C2FFC...@home.com...

[snipped]

> push @list, [$File::Find::name, (stat _)[4]]

Also note that (stat _)[4] refers to the UID for a file but this is not
implemented under Windows and will always return zero!

--
Chris Eustace (whoops ... missing from my previous post!!)


Godzilla!

unread,
Feb 27, 2002, 12:42:26 AM2/27/02
to
Martien Verbruggen wrote:

> Godzilla! wrote:
> > Fr...@PleaseNoSpam.com wrote:

(snipped)

> Nonsense.

Hoo! Hoo! Such an entertaining Village Idiot!
Rather comical this way you have of blowing
spittle while you rant and rave.

Reminds me of my high school typing teacher,
Mrs. Icenogle. She was always pissed at me
about whatever, mostly my typing faster than
her with less errors. Constantly lecturing me
and blowing spittle in my face. Gross.

Seems a similar situation, with my being such
a significantly better programmer than you.


I understand you are a high school dropout, Frank.

Godzilla!

Helgi Briem

unread,
Feb 27, 2002, 6:24:22 AM2/27/02
to
On Wed, 27 Feb 2002 01:01:32 GMT, Fr...@PleaseNoSpam.com
wrote:

>I generate a list of the files in C:\WIN\TEMP with the Perl script
>below (Win98SE). I then use the list (H:\filelist.txt) to delete
>files in C:\WinTemp, using a Winbatch-scriptfile during start-up.
>This works fine but is slow and not very elegant.
>Can anybody please show me how to delete the files in the
> list within the Perl script?

perledoc -f unlink.

typical usage:

unlink $file or die "Cannot delete $file:$!\n"

However, you also need to either escape your backslashes,
ie replace \ with \\ in file paths or better yet, replace
them with forward slashes:

> my $outfile = 'H:\filelist.txt' ;

my $outfile = 'H:/filelist.txt' ;

--
Regards, Helgi Briem
helgi AT decode DOT is

Godzilla!

unread,
Feb 27, 2002, 11:01:13 AM2/27/02
to
Helgi Briem wrote:

> Fred wrote:

(snipped)

> > I generate a list of the files in C:\WIN\TEMP with the Perl script

> However, you also need to either escape your backslashes,


> ie replace \ with \\ in file paths or better yet, replace
> them with forward slashes:

> > my $outfile = 'H:\filelist.txt' ;
> my $outfile = 'H:/filelist.txt' ;


#!perl

print 'apostrophe\enclosed\strings\need\not\to\be\escaped';


Godzilla!

Tramm Hudson

unread,
Feb 27, 2002, 11:01:33 AM2/27/02
to
[ Posted and cc'd to cited author ]

Helgi Briem <he...@decode.is> wrote:


> Fr...@PleaseNoSpam.com wrote:
> However, you also need to either escape your backslashes,
> ie replace \ with \\ in file paths or better yet, replace
> them with forward slashes:
>
> > my $outfile = 'H:\filelist.txt' ;
> my $outfile = 'H:/filelist.txt' ;

There is no need to escape the backslashes inside of the
single quotes. While in general it is better to use the
Unix path separator, it is not necessary in this case.

$ perl -e "print 'H:\filelist.txt'"
H:\filelist.txt

Trammell
--
-----|----- hud...@swcp.com H 240-476-1373
*>=====[]L\ Trammel...@celera.com W 240-453-3317
' -'-`- http://www.swcp.com/~hudson/ KC5RNF

Andrew Harton

unread,
Feb 27, 2002, 11:14:39 AM2/27/02
to
"Godzilla!" <godz...@stomp.stomp.tokyo> wrote in message
news:3C7D02C9...@stomp.stomp.tokyo...

#!perl

print 'sometimes\they\do\';

...as discussed in a different thread recently.

Andrew


--
$s="acehJklnoPrstu ";$_="4dbce078c32ae92a6e30152a";
split//;for(0..$#_){print substr($s,hex $_[$_],1);}


Godzilla!

unread,
Feb 27, 2002, 11:24:49 AM2/27/02
to
Andrew Harton wrote:


> Godzilla! wrote:
> > Helgi Briem wrote:
> > > Fred wrote:

(snipped)

> > > > I generate a list of the files in C:\WIN\TEMP with the Perl script

> > > However, you also need to either escape your backslashes,
> > > ie replace \ with \\ in file paths or better yet, replace
> > > them with forward slashes:

> > > > my $outfile = 'H:\filelist.txt' ;
> > > my $outfile = 'H:/filelist.txt' ;

> > #!perl

> > print 'apostrophe\enclosed\strings\need\not\to\be\escaped';

> print 'sometimes\they\do\';

> ...as discussed in a different thread recently.


In what manner are your comments intelligently related
to this thread's topic?


Godzilla!

Fr...@nospam.net

unread,
Feb 27, 2002, 7:29:59 PM2/27/02
to

Chris, thank you for your interesting hint. Yes, I copied the code from
a script for Unix. I corrected everything that did not work in Win98. I
could not find any info about (stat_)[4]. Therefore I tried all numbers
between [1] and [12] - it made no difference. After your message at
least I know now why.

----- Fred

Fr...@nospam.net

unread,
Feb 27, 2002, 8:03:16 PM2/27/02
to

Chris, thank you very much for the help. I had tried many hours and all
kinds of string modifications without success because I was always using
unlink $_;

Now using
for (@list) {
s/\//\\/;
unlink $_->[0];
}
Everything works perfect...

Fred

Fr...@nospam.net

unread,
Feb 27, 2002, 8:13:00 PM2/27/02
to


Helgi,

Thank you for your suggestion about the slashes. Yes, my list had a mix
of forward and back-slashes in every line. I added the code
s/\//\\/;
and now it works fine.

Fred

Fr...@nospam.net

unread,
Feb 27, 2002, 8:28:55 PM2/27/02
to

Jon Ericson wrote:
>
> Fr...@PleaseNoSpam.com writes:
>
> > Can anybody please show me how to delete the files in the list
> > within the Perl script?
>
> perldoc -f unlink
>
> Jon
> --

Jon,

Thank you for the tip. However, in my opinion, "perldoc -f unlink" is
_very_ meager and practically useless. I also have 4 Perl books. But
without the help of this Newsgroup (especially Chris Eustace) I would
have been completely lost.

--- Fred

Jon Ericson

unread,
Feb 27, 2002, 9:36:34 PM2/27/02
to
Fr...@NoSpam.net writes:

> Jon Ericson wrote:
>>
>> Fr...@PleaseNoSpam.com writes:
>>
>> > Can anybody please show me how to delete the files in the list
>> > within the Perl script?
>>
>> perldoc -f unlink
>>

> Thank you for the tip. However, in my opinion, "perldoc -f unlink" is


> _very_ meager and practically useless. I also have 4 Perl books. But
> without the help of this Newsgroup (especially Chris Eustace) I would
> have been completely lost.

Some points:

* "How do I delete a file within a perl script?" is a fairly common
question among beginning perl programmers. Often times people just
need to know the name of the function. When I was learning perl, I
needed that little hint myself.

* I'm glad you got the help you were looking for, but your question
could have been clearer. In particular you didn't your attempt to use
unlink itself.

* If the documentation is inadequate, submit a bug report or better
yet a patch. I find the documentation to be terse, rather than
meager, and helpful, rather than practically useless.

* I'm not sure what having 4 Perl books has to do with anything.

* You're welcome.

Uri Guttman

unread,
Feb 27, 2002, 11:48:23 PM2/27/02
to
>>>>> "F" == Fred <Fr...@NoSpam.net> writes:

F> s/\//\\/;

ewww. please learn to use alternate delimiters. and it appears all you do
is translate / to \ so tr is faster and clearer:

tr[/][\\] ;

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
-- Stem is an Open Source Network Development Toolkit and Application Suite -
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

Helgi Briem

unread,
Feb 28, 2002, 6:00:50 AM2/28/02
to
On Thu, 28 Feb 2002 01:28:55 GMT, Fr...@NoSpam.net wrote:
>> > Can anybody please show me how to delete the files in the list
>> > within the Perl script?
>>
>> perldoc -f unlink

>Thank you for the tip. However, in my opinion, "perldoc -f unlink" is


>_very_ meager and practically useless. I also have 4 Perl books. But
>without the help of this Newsgroup (especially Chris Eustace) I would
>have been completely lost.

What on earth do you mean?!? Here is the entry:

----------------------
unlink LIST

unlink Deletes a list of files. Returns the number
of files successfully deleted.

$cnt = unlink 'a', 'b', 'c';
unlink @goners;
unlink <*.bak>;

Note: `unlink' will not delete directories unless
you are superuser and the -U flag is supplied to
Perl. Even if these conditions are met, be warned
that unlinking a directory can inflict damage on
your filesystem. Use `rmdir' instead.

If LIST is omitted, uses `$_'.
------------------------

How could anything be clearer? I don't get it.

Fred

unread,
Feb 28, 2002, 10:32:21 AM2/28/02
to

Sorry I did not make that clear enough. Yes - it's all there if you
already know Perl well. But I am still in a learning phase and I need to
see actual working code, not just a line out of context.

I was wasting many hours trying to work with
unlink @list;
and
unlink $_;

until somebody in this NG told me to use
for (@list) {
unlink $_->[0];
}

after which it took just 20 seconds to get my script working...

Fred

Fred

unread,
Feb 28, 2002, 10:38:12 AM2/28/02
to

Uri Guttman wrote:
>
> >>>>> "F" == Fred <Fr...@NoSpam.net> writes:
>
> F> s/\//\\/;
>
> ewww. please learn to use alternate delimiters. and it appears all you do
> is translate / to \ so tr is faster and clearer:
>
> tr[/][\\] ;
>
> uri
>

Thank you Uri, I agree that this is much clearer and less prone to
errors.

--- Fred

Fred

unread,
Feb 28, 2002, 10:52:04 AM2/28/02
to

Uri,
I have a question. Why
tr[/][\\] ;

and not
tr[\/][\\] ;

--- Fred

Uri Guttman

unread,
Feb 28, 2002, 11:15:00 AM2/28/02
to
>>>>> "F" == Fred <Fr...@NoSpam.net> writes:

F> I have a question. Why
F> tr[/][\\] ;

F> and not
F> tr[\/][\\] ;

well, think about it. what is the delimiter there? you only need to
escape delimiters and \ itself in tr. / is NOT a special char if it is
not the delimiter (in any stringy thing).

Helgi Briem

unread,
Feb 28, 2002, 11:36:51 AM2/28/02
to
On Thu, 28 Feb 2002 15:32:21 GMT, Fred <Fr...@NoSpam.net>
wrote:

>Sorry I did not make that clear enough. Yes - it's all there if you
>already know Perl well. But I am still in a learning phase and I need to
>see actual working code, not just a line out of context.
>
>I was wasting many hours trying to work with
> unlink @list;
>and
> unlink $_;
>
>until somebody in this NG told me to use
> for (@list) {
> unlink $_->[0];
> }
>

But that is completely unnecessary.

Below is a complete script that illustrates what I mean:
Note the chdir in line 5. Personally, I never use chdir
unless I absolutely have to for some external program
to work. Instead I append the full path to the filename
like so: for (files) { unlink "$dir/$_" or die "Cannot
delete $dir/$_:$!\n";

Also note the "or die $!" construct used to get errors
from system operations. These are essential and
save thousands of hours of headscratching. You can
also use warn instead of die.

__START__
#!/usr/bin/perl -w
use strict;
my $dir = "C:/tmp/foo";
if (not -e $dir) { mkdir $dir, 0700 or die "Cannot mkdir
%dir:$!\n"; }

chdir $dir or die "Cannot chdir to $dir:$!\n";

# This example makes three files named A.txt, B.txt and
# C.txt and then deletes them.
for ("A".."C")
{
open OUT, ">$_.txt" or die "Cannot open $_.txt for
writing:$!\n";
print OUT "This is file $_.txt\n";
close OUT or die "Cannot close $_.txt:$!\n";
}

opendir DIR, $dir or die "Cannot opendir $dir:$!\n";
my @files = grep /\.txt$/,readdir DIR;
closedir DIR;

print join "\n", (@files);

unlink @files or die "Cannot delete $_:$!\n";
# You can also do:
# for (@files) { unlink $_ or die "Cannot delete $_:$!\n"; }

__END__

Douglas Wilson

unread,
Feb 28, 2002, 12:45:24 PM2/28/02
to
On Wed, 27 Feb 2002 01:01:32 GMT, Fr...@PleaseNoSpam.com wrote:

>I generate a list of the files in C:\WIN\TEMP with the Perl script below
>(Win98SE).

Why generate a list at all?

use File::Find;

finddepth(sub {
return if -d;
return unless -M _ > 1;
print "$File::Find::name\n";
unlink;
}, 'C:\WIN\TEMP');

HTH,
Douglas Wilson

Fred

unread,
Mar 1, 2002, 1:40:10 AM3/1/02
to

If I first generate a list I can filter out certain files and I can
change the forward-slashes to backslashes before using unlink....

--- Fred

Helgi Briem

unread,
Mar 1, 2002, 4:34:44 AM3/1/02
to
On Fri, 01 Mar 2002 06:40:10 GMT, Fred <Fr...@NoSpam.net>
wrote:

>Douglas Wilson wrote:
>> Why generate a list at all?
>> use File::Find;
>>
>> finddepth(sub {
>> return if -d;
>> return unless -M _ > 1;
>> print "$File::Find::name\n";
>> unlink;
>> }, 'C:\WIN\TEMP');

>If I first generate a list I can filter out certain files and I can


>change the forward-slashes to backslashes before using unlink....

You can do both easily with Douglas' script.

Jürgen Exner

unread,
Mar 1, 2002, 12:06:12 PM3/1/02
to
"Fred" <Fr...@NoSpam.net> wrote in message news:3C7F225E...@cox.net...

> If I first generate a list I can filter out certain files and I can

That's what the sub (or wanted function) will do automatically.

> change the forward-slashes to backslashes before using unlink....

And why would you want to do that?
You are aware, that Perl handles forward slashes just fine, even on Windows?

jue


Fred

unread,
Mar 1, 2002, 5:55:26 PM3/1/02
to

Helgi, you are right, I tried it with the filter and the substitution
and it works fine....

Fred

Fred

unread,
Mar 2, 2002, 4:31:04 PM3/2/02
to

When I started this project I wanted to eliminate all possible
conflicts, including the forward/back slash issue. When the script was
finally running OK I did not go back.

My reasoning was (and may-be I am wrong):

In Perl, forward slashes work if you use double quotes and back slashes
work if you use single quotes. The filelist I generate always has mixed
slashes, like C:/Win/Temp\foo.tmp
So, in order to use single quotes, I convert the forward slashes first.
But I will try tonight (Pacific Time) to work without slash conversion
and then report back.
--- Fred

Fred

unread,
Mar 2, 2002, 6:10:13 PM3/2/02
to

Jürgen, you are right. I took the conversion out
# s/\//\\/;
and the script works the same.....

Thanks, Fred

Fred

unread,
Mar 2, 2002, 6:15:35 PM3/2/02
to
Helgi Briem wrote:

<snip>

Helgi, thank you for the additional info on "unlink". This shows again
that in Perl the same result can be reached in many different ways...

Fred

Jürgen Exner

unread,
Mar 4, 2002, 11:56:52 AM3/4/02
to
"Fred" <Fr...@NoSpam.net> wrote in message news:3C8144A6...@cox.net...

> In Perl, forward slashes work if you use double quotes and back slashes
> work if you use single quotes.

Nope, that's not right.
In Perl (on Windows) you can use forward or backward slashes as you please.
And forward slashes are a lot less trouble.

jue


Josef Drexler

unread,
Mar 4, 2002, 12:02:26 PM3/4/02
to
Sorry, Helgi Briem, could you repeat that? I wasn't paying attention:

> unlink @files or die "Cannot delete $_:$!\n";

The "die" only gets called if *no* files are unlinked, which is not what
you want here, I think.

In addition, $_ is not set to the file name that failed. It is in fact not
touched by unlink at all, as far as I can see. If it is, that isn't
documented and should not be relied on.

> for (@files) { unlink $_ or die "Cannot delete $_:$!\n"; }

This does work, though.

--
Josef Drexler | http://publish.uwo.ca/~jdrexler/
---------------------------------+----------------------------------------
Please Conserve Gravity: Don't | Email address is *valid*.
hang your clothes - pile them up| Don't remove the "nospam" part.

Benjamin Goldberg

unread,
Mar 6, 2002, 12:24:47 AM3/6/02
to
Fred wrote:
> "Jürgen Exner" wrote:
> > Fred wrote:
> >
> > > If I first generate a list I can filter out certain files and I
> > > can
> >
> > That's what the sub (or wanted function) will do automatically.
> >
> > > change the forward-slashes to backslashes before using unlink....
> >
> > And why would you want to do that?
> > You are aware, that Perl handles forward slashes just fine, even on
> > Windows?
> >
> > jue
>
> When I started this project I wanted to eliminate all possible
> conflicts, including the forward/back slash issue. When the script was
> finally running OK I did not go back.
>
> My reasoning was (and may-be I am wrong):
>
> In Perl, forward slashes work if you use double quotes and back
> slashes work if you use single quotes.

In Perl, forward slashes can be put in double or single quotes, and
backslashes can be put in double quotes if you double them up, and in
single quotes with or without doubleing them up.

> The filelist I generate always has mixed
> slashes, like C:/Win/Temp\foo.tmp

So? That works fine.

unlink doesn't care what kind of slashes are passed to it.

> So, in order to use single quotes, I convert the forward slashes
> first.

Huh?

> But I will try tonight (Pacific Time) to work without slash conversion
> and then report back.

--
print reverse( ",rekcah", " lreP", " rehtona", " tsuJ" )."\n";

0 new messages