Re: opening consecutive files
by Abigail-II (Bishop) on Jun 27, 2003 at 13:08 UTC
|
You don't show us the code with the counter, so it's hard
to say where you went wrong. Here's a loop that starts with
opening graph_set_1.out, and continues to increase
the number until there's no matching file.
for (my $c = 1;; $c ++) {
my $file = "graph_set_$c.out";
last unless -f $file;
open my $fh => "<", $file or die "Failed to open $file: $!";
... # Do something with $fh.
}
Abigail | [reply] [d/l] |
|
|
I have added the code that you have supplied.
what I want to do is match the specified strings from each graph_set.out file and print strings into .txt file.
It's not printing anything into the .txt file ? ?
#!/usr/local/bin/perl
for (my $c = 1;; $c ++) {
my $file = "graph_set_$c.out";
last unless -f $file;
open my $fh => "<", $file or die "Failed to open $file: $!";
local $/ = undef; # undef record seperator
my $string = <IN>; # read whole file into string
close (IN);
my @gset_match = ($string =~ /([A-Z]\s\d+,\s\d+\(\s*\d+\))/g);
open (TEXT, ">graph_set.txt") or die "Can't create graph_set.txt: $!\n
+";
foreach $_(@gset_match) { print TEXT "$_\n"; }
close TEXT;
}
| [reply] [d/l] |
|
|
You are reading from a handle named IN, while the
open opens a handle $fh. That isn't going to work.
If you turn warnings on (which usually is a good idea),
Perl would have told you that you were reading from an
unopened filehandle.
Abigail
| [reply] |
Re: opening consecutive files
by dragonchild (Archbishop) on Jun 27, 2003 at 12:58 UTC
|
use strict;
use warnings;
use IO::File;
foreach my $i (1 .. 30)
{
my $fh = IO::File->new("graph_set_$i.out")
|| die "Cannot open $i'th file\n";
# Use $fh here
$fh->close;
}
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified. | [reply] [d/l] |
Re: opening consecutive files
by Zaxo (Archbishop) on Jun 27, 2003 at 13:23 UTC
|
There are two steps to this. First you need to get a list of file names and sort them in the desired order. Then, open the files in a for loop over the sorted list.
my $path = '/path/to/dir';
my @names = glob $path . '/graph_set_*.out';
# @names is in alpha order, so sort numerically
my @sorted_names =
sort {
my ($x, $y);
$a =~ /graph_set_(\d+)\.out$/ and $x = $1;
$b =~ /graph_set_(\d+)\.out$/ and $y = $1;
$x <=> $y
} @names;
# That may benefit from a Schwartzian Transform
# Now, do the loop
for (@sorted_names) {
open local(*IN), "< $_" or die $!;
# ...
close IN or die $!;
}
If you can write for recent enough perl, three-arg open and lexical filehandles ('open my $fh, '<', $_ or die $!;') would be good. If you want all the handles open at the same time, push $fh onto an array or assign array elements to it.
After Compline, Zaxo | [reply] [d/l] |
Re: opening consecutive files
by BrowserUk (Patriarch) on Jun 27, 2003 at 13:34 UTC
|
Rather than trying to open 30 files when some or all of them may not exist, and dieing if one of them doesn't (unless that makes sense). You could let perl tell you which files exist and just open those that do.
while( my $file = <graph_set_*.out> ) {
next unless $file =~ m[graph_set_[123]?[0-9].out];
open IN, '<', $file
or warn "Couldn't open file $file because $!";
#Do stuff
close IN;
}
The caveat is that you may not get the files in the order you want them if that is important. They will be in sorted order (as of 5.8 I think) but as your numbers don't appear to have leading zeros, they will come in ascii order
1 10 11 12 13 14 15 16 17 18 19 2 20 21 22 23 24 25 26 27 28 29 3 30 4 5 6 7 8 9
If that's a problem, then you could do
for $file (sort{ $a=~/(\d+)/ <=> $b=~/(\d+)/ } <graph_set_*.out> ) {
open...
....
close...
}
Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
| [reply] [d/l] [select] |
|
|
there is nothing printing into the txt file.
is there anything obviously wrong ?
I know the pattern matching code is right.
#!/usr/local/bin/perl
while( my $file = <graph_set_*.out> ) {
next unless $file =~ m[graph_set_[123]?[0-9].out];
open IN, '<', $file
or warn "Couldn't open file $file because $!";
local $/ = undef; # undef record seperator
my $string = <IN>; # read whole file into string
close IN;
}
my @gset_match = ($string =~ /([A-Z]\s\d+,\s\d+\(\s*\d+\))/g);
open (TEXT, ">graph_set.txt") or die "Can't create graph_set.txt: $!\n
+";
foreach $_(@gset_match) { print TEXT "$_\n"; }
close TEXT;
| [reply] [d/l] |
|
|
| [reply] |
Re: opening consecutive files
by bobn (Chaplain) on Jun 27, 2003 at 13:15 UTC
|
#!/usr/local/bin/perl
# NOT TESTED
@files = map {$_->[1]}
sort {$a->[0] <=> $b->[0] }
map { /^graph_set_([[0-9]+).out$/; [ $1, $_ ] }
grep { /^graph_set_[0-9]+.out$/ }
glob('graph_set_*');
# lookup schwartzian transform, then read the preceding from the botto
+m up
for (@files)
{
open(F, $mode, $_);
# do whatever
close F;
}
--Bob Niederman, http://bob-n.com | [reply] [d/l] |