find out all .txt files in a dir recursively

Y

yihucd

I wish to be able to find all .txt files in a dir recursively using
perl script, can anyone tell me how to write this perl script?
 
J

J. Gleixner

I wish to be able to find all .txt files in a dir recursively using
perl script, can anyone tell me how to write this perl script?

Check the documentation for File::Find.

perldoc File::Find
 
U

usenet

I wish to be able to find all .txt files in a dir recursively using
perl script, can anyone tell me how to write this perl script?

(Well, Boys & Girls, it's time for yet another message from DavidFilmer
on the wonders of the module IO::All. What's that - you don't have
IO::All on your system??? Egads! Well, no problem - just hop over to
http://search.cpan.org/~ingy/IO-All-0.33 and forget all those oddball
File::Whatever modules). Matches "*.txt" in case INsensitive manner:)

#!/usr/bin/perl
use strict; use warnings;
use IO::All;

my $root_dir = "/path/to/my/directory";
print map {"$_\n"}
io($root_dir) -> filter(sub { $_->name =~ /\.txt$/i } )
-> all_files;
__END__
 
M

Matt Garrish

perldoc readdir

That's not particularly helpful. What happens when you run that command?

Most people would recommend File::Find or File::Finder over rolling your
own, unless you're just really bored and want to re-invent the wheel to
prove you can do it (which sometimes has it benefits).

Matt
 
U

usenet

Or, suppose you wanted to get more fancy. Suppose you want all *.txt
(case insensitive) recursed only two directories deep (hah!) which are
smaller than 1000 bytes and whose first line contains the string
"spooler" (case sensitive):

use strict; use warnings;
use IO::All;

my $root_dir = "/tmp";
print map {"$_\n"}
io($root_dir) -> filter(sub { $_->name =~ /\.txt$/i
&& $_->size < 1000
&& ($_->head)[0] =~ /spooler/
} )
-> all_files(2);
__END__
 
T

Tad McClellan

I wish to be able to find all .txt files in a dir recursively using
perl script, can anyone tell me how to write this perl script?


perl -MFile::Find -le 'find sub{print if /\.txt$/}, "."'
 
A

A. Sinan Unur

(e-mail address removed) wrote in
(Well, Boys & Girls, it's time for yet another message from
DavidFilmer on the wonders of the module IO::All.

Using File::Find has its advantages, especially when a large number of
files need to be processed. Think of the difference between:

for my $line (<FILE>) {
# ...
}

versus

while (my $line = <FILE>) {
# ...
}

Compare:

D:\Home\asu1\UseNet\clpmisc> cat ls-ff.pl
#!/usr/bin/perl

use strict;
use warnings;

use File::Find;
use File::Spec::Functions qw( rootdir );

find(\&wanted, rootdir());

print results(), "\n";


{
my $txt_files = 0;
sub wanted {
$txt_files += 1 if m{ \.txt \z }imsx;
}

sub results {
"Found $txt_files text files\n";
}
}

Found 2893 text files

TimeThis : Command Line : ls-ff.pl
TimeThis : Start Time : Thu Nov 03 21:04:06 2005
TimeThis : End Time : Thu Nov 03 21:04:25 2005
TimeThis : Elapsed Time : 00:00:18.062

versus

D:\Home\asu1\UseNet\clpmisc> cat ls-ioa.pl
#!/usr/bin/perl

use strict;
use warnings;

use IO::All;

my @txt_files = io->rootdir->filter(sub {
$_->name =~ m{ \.txt \z }imsx;
} )->All_Files;

print scalar @txt_files, " text files\n";

__END__

D:\Home\asu1\UseNet\clpmisc> timethis ls-ioa.pl

2893 text files

TimeThis : Command Line : ls-ioa.pl
TimeThis : Start Time : Thu Nov 03 20:59:41 2005
TimeThis : End Time : Thu Nov 03 21:00:31 2005
TimeThis : Elapsed Time : 00:00:49.968

For reference:

C:\opt\support> diruse /m d:

Size (mb) Files Directory
14411.99 44956 TOTAL: D:\

Sinan
 
D

Dr.Ruud

Abigail schreef:
Dr.Ruud:

I wouldn't.

I wouldn't use a perl script to do this -- there's a tool specially
written to do this kind of stuff, and it's called "find". (Yes, that's
available for Windozes too). From a Perl script, I'd simply call that
program:


my @files = `find $dir -name '*.txt'`;

I like IO:All very much. It bit me today though, on a Windows system
while converting jpegs with GD; but changing

$io_dst < $dst_img->jpeg(90);

to

$io_dst->binary < $dst_img->jpeg(90);

made the pictures look OK again.


I can't get it to normalize the path separators yet, it returns names
with these hideous backslashes even when you give it 'c:/images/' as a
dir.

OK, let's hack All.pm and add a line to its sub new:

my $name = shift;
$name =~ s~\\~/~g if $^O eq 'MSWin32';

Not a nice fix, but for now that solved my problem with it.
 
D

Dr.Ruud

Dr.Ruud:

I did this to IO/All.pm:
I can't get it to normalize the path separators yet, it returns names
with these hideous backslashes even when you give it 'c:/images/' as a
dir.

OK, let's hack All.pm and add a line to its sub new:

my $name = shift;
$name =~ s~\\~/~g if $^O eq 'MSWin32';

Not a nice fix, but for now that solved my problem with it.

(I hope this is a SAQ.)

Is there a more general way to not receive values with '\' or use '\\'
(and Mac ';' and whatever) when dealing with the file system?

I like my Perl code to be '/'-aware-only, wherever it is used.
 
A

Anno Siegel

[...]
OK, let's hack All.pm and add a line to its sub new:

my $name = shift;
$name =~ s~\\~/~g if $^O eq 'MSWin32';

Not a nice fix, but for now that solved my problem with it.

To do it by the book, one could use a subclass that does the backslash
thingie. Install this in an appropriate place:

package IO::All::Backslash_free;
use warnings; use strict;

use IO::All;
our @ISA = 'IO::All'; # IO::All has issues with "use base"

sub new {
my ( $class, $name) = @_;
$name =~ s~\\~/~g if $^O eq 'MSWin32';
$class->SUPER::new( $name);
}

1;

Then use "IO::All::Backslash_free" instead of IO::All.

Of course, it is now necessary find all places that use IO::All and
change them. Doing it by the book often has disadvantages of this
nature.

Anno
 
U

usenet

A. Sinan Unur said:
Using File::Find has its advantages [over IO::All], especially when a large number of
files need to be processed. Think of the difference between: [snipped benchmarks]

Agreed, of course. IO::All is a "higher level" module. Performance is
the price you pay for the additional convenience and ease of
programming. But Perl programmers are accustomed to the
convenience/performance trade-off - after all, if we were really THAT
concerned with performance, we'd be pounding out C++
 
T

Tad McClellan

emallove said:
^^^^^^^^^^^
^^^^^^^^^^^

perl -e ' \
opendir(d,"."); \
foreach (readdir(d)) { \
print "$_\n" if (/.txt/); \
} \
closedir(d);'


That is the answer to a question other than the one that was asked.
 
A

Anno Siegel

Samwyse said:
How about this, in 'package main':

use IO::All;
BEGIN {
our $previous_new = \&IO::All::new;
}
sub IO::All::new {
my ( $class, $name) = @_;
$name =~ s~\\~/~g if $^O eq 'MSWin32';
&$previous_new(@_);
}

That avoids changing the module source .../IO/All.pm, but it's still an
intrusion in the All::New name space.

If I'd use the technique, I wouldn't put previous_new() in a package I'm
actually using.

Anno
 
D

Dr.Ruud

Samwyse:
Anno Siegel:

How about this, in 'package main':

use IO::All;
BEGIN {
our $previous_new = \&IO::All::new;
}
sub IO::All::new {
my ( $class, $name) = @_;
$name =~ s~\\~/~g if $^O eq 'MSWin32';
&$previous_new(@_);
}

The sub new in All.pm does a bit more:

sub new {
my $package = ref($self) || $self;
my $new = bless Symbol::gensym(), $package;
$new->package($package);
$new->_copy_from($self) if ref($self);

my $name = shift;
### $name =~ s~\\~/~g if $^O eq 'MSWin32';

return $name if UNIVERSAL::isa($name, 'IO::All');
return $new->_init unless defined $name;
return $new->handle($name)
if UNIVERSAL::isa($name, 'GLOB') or ref(\ $name) eq 'GLOB';
# WWW - link is first because a link to a dir returns true for
# both -l and -d.
return $new->link($name) if -l $name;
return $new->file($name) if -f $name;
return $new->dir($name) if -d $name;
return $new->$1($name) if $name =~ /^([a-z]{3,8}):/;
return $new->socket($name) if $name =~ /^[\w\-\.]*:\d{1,5}$/;
return $new->pipe($name)
if $name =~ s/^\s*\|\s*// or $name =~ s/\s*\|\s*$//;
return $new->string if $name eq '$';
return $new->stdio if $name eq '-';
return $new->stderr if $name eq '=';
return $new->temp if $name eq '?';
$new->name($name);
$new->_init;
}
 
E

Eric J. Roode

(e-mail address removed) wrote in @g43g2000cwa.googlegroups.com:
I wish to be able to find all .txt files in a dir recursively using
perl script, can anyone tell me how to write this perl script?

use Iterator::IO;
use Iterator::Util;

my $txtfiles = igrep {/\.txt\z/} idir_walk;
while ($txtfiles->isnt_exhausted)
{
print $txtfiles->value, "\n";
}

--
Eric
`$=`;$_=\%!;($_)=/(.)/;$==++$|;($.,$/,$,,$\,$",$;,$^,$#,$~,$*,$:,@%)=(
$!=~/(.)(.).(.)(.)(.)(.)..(.)(.)(.)..(.)......(.)/,$"),$=++;$.++;$.++;
$_++;$_++;($_,$\,$,)=($~.$"."$;$/$%[$?]$_$\$,$:$%[$?]",$"&$~,$#,);$,++
;$,++;$^|=$";`$_$\$,$/$:$;$~$*$%[$?]$.$~$*${#}$%[$?]$;$\$"$^$~$*.>&$=`
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top