Re: Array size too big?
by davido (Cardinal) on Nov 19, 2017 at 23:30 UTC
|
Your scroll-back buffer isn't large enough to accommodate the entire output. If you're using a *nix environment, try this:
./myscript |wc -l
In other words, run your script, and pipe its output to wc -l, which will be a line count. It should be the size of $count plus one (because "no. of records: $count \n" is printed in-band. If you wish to make the header out of band, print it to STDERR, which won't be counted by wc.
I'll assert that wc -l will probably say "5175" (or something close). If it doesn't, your input file isn't as big as you think it is, or is using some other record separator other than a standard newline.
Your code above is correct, though would be better written like this:
my $file_in = "C:/Users/Joe/Documents/Geneaology/birdt.ged";
open my $FILE, '<', $file_in or die $!;
while(<$FILE>) {
print "$.\t$_";
}
warn "no. of records read: $.\n";
...recognizing that you can't print a total number of records until you've gotten through the last one. Better, because it avoids slurping the entire file into memory all at once. Instead, it just reads in one record at a time, so it is less of a resource hog.
And now that I've looked more closely at your file name, it seems unlikely that you are using a *nix operating system, so wc -l probably isn't available to you unless you install something like CoreUtils: http://gnuwin32.sourceforge.net/packages/coreutils.htm. This does lead me to wonder why you have #!/usr/bin/perl at the top of your script. Does your Windows system have a program named perl living at C:\usr\bin?
| [reply] [d/l] [select] |
|
|
Thanks for this, Dave, I appreciate the time and effort you have taken to examine and respond.
My Perl.exe, as seen on the screen image I referred to, is located as :
c:\Dwimperl\usr\bin\Perl.exe
My problem is this is only a small test GEDCOM file that I am reading. My main file is 9,000 records long :( Looks like I will need to alter my programming strategy and deal with a few lines at a time.
regards,
Jill
| [reply] |
Re: Array size too big?
by huck (Prior) on Nov 19, 2017 at 22:53 UTC
|
Did you at all consider that the first 722 just scrolled off the top of the screen?
And the records in @ged already have a "newline", so there is no need to add another at the print stage.
| [reply] |
|
|
| [reply] |
|
|
You now seem to understand that it is not a program problem but a problem with how many lines you can see in your output window.
One option would be to output to a file, such as
perl Test_1..pl >"C:/Users/Joe/Documents/Genealogy/birdt.ged.txt"
or
#!/usr/bin/perl
use strict;
use warnings;
my $file_in = "C:/Users/Joe/Documents/Genealogy/birdt.ged";
open my $FILE, "<", $file_in or die "could not open $file_in $!";
+ # three-argument open syntax
my @ged = <$FILE>; # slurp the file contents into
+ @ged
open my $OUTPUT,'>',$file_in.'.txt.' or die "could not open $file_in.
+txt $!";
select $OUTPUT;
my $count = $.;
print "no. of records: $count \n" ; # counting the number of recor
+ds
my $i=0; # stepping through the array $
+count = 5174
for ($i= 0; $i<$count; $i=$i+1)
{print "$i $ged[$i]\n"; }
or you could modify your cmd output buffer size.
On the output window, to the left of C;\Dwimperl\... is a black box with c:\ in it. Click on it, select properties, then the layout tab. Now increase the number of lines in the screen buffer size height, and press ok. Another box should open where you will want to select "save properties for future windows with the same title", then press ok. This should increase the screen buffers size for future runs of perl from padre | [reply] [d/l] [select] |
Re: Array size too big?
by roboticus (Chancellor) on Nov 19, 2017 at 22:57 UTC
|
JillB:
Looking at your code, I can't see anything that would cause the symptoms you describe. I suspect that you simply filled your scrollback buffer and can't scroll backwards far enough to see the start of the run. You could check that by changing your for loop at the end to something like:
for ($i= 0; $i<200; $i=$i+1)
To show only the first couple hundred lines of the file.
...roboticus
When your only tool is a hammer, all problems look like your thumb. | [reply] [d/l] |
|
|
Thanks for this suggestion, roboticus. I even increased the limit to read 4000 records, and they all appeared OK.
Took it to 5000 records, and the top 550 records disappeared
So it looks like a buffer problem, as suggested below
| [reply] |
Re: Array size too big?
by 1nickt (Canon) on Nov 19, 2017 at 22:39 UTC
|
use strict; use warnings;
my $file_in = "C:/Users/Joe/Documents/Genealogy/birdt.ged";
open my $FILE, "<", $file_in or die "could not open $file_in $!";
while ( my $line = <$FILE> ) {
print "$. $line";
}
close $FILE or die "could not close $file_in $!";
__END__
Although I would rather use the convenience of a filehandling module like Path::Tiny :
use strict; use warnings;
use Path::Tiny; # imports path()
my $file_in = "C:/Users/Joe/Documents/Genealogy/birdt.ged";
my $line_num = 0;
for my $line ( path( $file_in )->lines ) {
print sprintf '%4d %s', ++$line_num, $line;
}
__END__
Hope this helps!
The way forward always starts with a minimal test.
| [reply] [d/l] [select] |
|
|
Thanks lnickt. I read the perlintro as suggested, but I preferred , in this instance , to work with an array, and to check the contents of the array. This is because further down the track of this program I want to manipulate the contents of some lines in the array, and add additional lines to the arrays.
| [reply] |
|
|
I preferred , in this instance , to work with an array, and to check the contents of the array. This is because further down the track of this program I want to manipulate the contents of some lines in the array, and add additional lines to the arrays.
It might still be worth considering doing the work in one pass while reading the file line-by-line. While 5174 lines is probably still small enough to fit into memory, if your file does grow, performance might suffer, and you might end up having to rewrite the program. The general approach would be to use a while (<$filehandle>) loop to read the file line-by-line and keep track of the current line number yourself or with Perl's special variable $.. For each line you read, either modify it or don't, and print it back out. When you hit the line number where you want to insert records, use additional print statements in an if to do so.
But of course I also understand the simplicity of just manipulating an array. Note that the core module Tie::File might be worth looking at, it will give you a normal-looking Perl array, but behind the scenes it is actually accessing the lines of the file, while keeping only some of them in memory. You can then do all your normal Perl array operations on it, including splice to remove and insert records, and the changes will be made to the file. While the module isn't necessarily the fastest when it comes to writing to the file, it does have the advantage to give you a pretty transparent interface and you don't have to worry about memory management.
| [reply] [d/l] [select] |
|
|
Hi, see my second example, showing how to get an array of the lines with Path::Tiny::lines() (which you should probably use with the chomp option if you are planning to do more than simply print the lines):
use strict; use warnings;
use Path::Tiny;
my $filename = "foobar.txt";
my @lines = path( $filename )->lines({ chomp => 1 });
# done!
The way forward always starts with a minimal test.
| [reply] [d/l] [select] |
Re: Array size too big?
by thanos1983 (Parson) on Nov 20, 2017 at 11:20 UTC
|
Hello JillB,
I just read your question and it looks like the fellow Monks have provided you with many answers to your problem, but still due to your buffered lines limitation on your terminal you are not able to see the complete output.
From what I understand you are running a WindowsOS, as fellow monk huck already proposed your options would be to increase your buffer or pipe the output of your script to a file and view the data from there. Another possibility would be to use a UnixOS approach as fellow Monk davido proposed. How to do that? Simply download Cygwin terminal where you can apply all the Unix commands such as perl myscript.pl | less and you will buffer the output. Give it a try.
Hope this helps, BR.
Seeking for Perl wisdom...on the process of learning...not there...yet!
| [reply] [d/l] [select] |
|
|
Windows already includes a similar utility called 'more'.
For Information, type:
help more
As you might expect, the normal usage is:
perl myscript.pl | more
| [reply] [d/l] [select] |