Re: printing specific lines
by esskar (Deacon) on Feb 27, 2005 at 21:10 UTC
|
as i understand: store the line number in a hash instead, so
my %lines = map { ($_, 1) } qw/1 3 5 7/;
open(IN, "<grep") or die;
while (<IN>) {
print OUT $_ if $lines{$.};
}
HTH | [reply] [d/l] |
Re: printing specific lines
by traveler (Parson) on Feb 27, 2005 at 21:22 UTC
|
If the text file could be large, consider
open (IN, "<grep");
my %lines;
while (<IN>){
$lines{$_} = 1;
}
close IN;
open (OUT, ">gout");
# assumes input data comes from stdin
while (<>){
print OUT $_ if exists $lines{$.};
}
close OUT;
Untested, but I think I got it right. Save the small stuff, not the big stuff. | [reply] [d/l] |
Re: printing specific lines
by ambrus (Abbot) on Feb 27, 2005 at 22:13 UTC
|
$ cat text
first
second
third
fourth
fifth
sixth
seventh
eighth
$ cat nums
1
4
6
7
$ ed -s text < nums
first
fourth
sixth
seventh
Update: this sucks if the text file is too large to load in memory. In that case,
Update: here's a perl solution too:
perl -we 'open N, "<", shift or die; $p = 0; while(defined($n = <N>))
+{ $s = <> for $p + 1 .. $n + 0; print $s; $p = $n; }' nums text
Update: if anyoune knows how to convert the above snippet so that it uses either $. or IO::Handle::input_line_number, please reply me, cause I can't figure out how to do that.
| [reply] [d/l] [select] |
Re: printing specific lines
by dmorelli (Scribe) on Feb 28, 2005 at 03:48 UTC
|
I'm surprised nobody mentioned using Tie::File so you can use the numeric values as array indices.
#! /usr/bin/perl -w
use strict;
use Fcntl 'O_RDONLY';
use Tie::File;
# Path to file containing lines as arg
my $linesPath = shift;
# Tie the file read-only, if you want to read only, to be safe
tie my @linesFile, 'Tie::File', $linesPath, mode => O_RDONLY
or die "Can't open file $linesPath: $!";
while(<DATA>) {
chomp;
# $_ - 1, I'm assuming that the list isn't 0-based
print "$linesFile[$_ - 1]\n";
}
untie @linesFile;
__DATA__
1
3
4
7
| [reply] [d/l] |
Re: printing specific lines
by thedoe (Monk) on Feb 27, 2005 at 21:04 UTC
|
I'm sorry, but I don't understand your question. Are the 1 3 5 7 the line numbers you want to print or are they the actual lines in a file? What is the output file you are are writing to, are you trying to print out to that file or STDOUT? | [reply] |
|
the line numbers to print are stored in a file.
1
3
5
text file
once upon a time
...
big bear
....
shot dead
so the lines i want to print are 1 3 and 5, to a separate output file
thanks
| [reply] [d/l] [select] |
Re: printing specific lines
by Anonymous Monk on Feb 27, 2005 at 21:03 UTC
|
open (OUT, ">gout");
while (<>){
chomp;
$line = $_;
push @array, $line;
}
print @array;
open (IN, "<grep");
while (<IN>){
next unless $. == $array[$i++];
print OUT $_;
#if ($. == @array) {print OUT $_}
}
| [reply] [d/l] |
|
next unless $. == $array[$i++];
to
next unless $. == $array[$i];
$i++;
and it should work.
Also, you should really add or die "open: $! to your open statement.
Update: and to eliminate a warning, you may want to replace
next unless $. == $array[$i++];
print OUT $_;
to
next unless $. == $array[$i];
print $_;
++$i < @array or last;
| [reply] [d/l] [select] |
Re: printing specific lines
by merlyn (Sage) on Feb 27, 2005 at 21:24 UTC
|
| [reply] |
|
| [reply] |
|
As someone who creates exercises for a living, this is exactly the kind of exercise I would create. I also note the absence of "real world" indicators in the question, again leading toward an abstract problem that someone would not have occur "in the wild".
No, I'll stand by my assessment. Homework, with some of the work done, but missing some essential piece. Nothing that should be answered, because the student should go back to the teacher for answers, not rely on the virtual brain of the monastery.
| [reply] |
Re: printing specific lines
by TedPride (Priest) on Feb 28, 2005 at 06:17 UTC
|
use strict;
my ($handle, @lines, $c);
open($handle, "lines");
@lines = <$handle>;
close($handle);
chomp @lines;
@lines = sort {$a <=> $b} @lines;
open($handle, "text");
while ($c <= $#lines) {
<$handle> for (($.)..($lines[$c++]-2));
print $_ = <$handle>;
}
close($handle);
This assumes that line 1 is considered the first line, not the second. It allows for line numbers given out of order, and doesn't require reading the entire text into memory at once. | [reply] [d/l] |
Re: printing specific lines
by chas (Priest) on Feb 27, 2005 at 21:22 UTC
|
You could, for example, make a hash with keys equal to the line numbers you want to print (and corresponding true values)
and use this to check whether a line should be printed as you loop.
(Update:Sorry, didn't see that this had been suggested.)
Are you collecting the line numbers from STDIN? (That's what it seems to be.) In that case, what does the "separate file" have to do with your code?
chas
(Update: Rewrote to fix error.)
| [reply] |
Re: printing specific lines
by Random_Walk (Prior) on Feb 28, 2005 at 15:32 UTC
|
#!/usr/bin/perl
use warnings;
use strict;
my @prints;
while (<DATA>) {
chomp;
$prints[--$_]="print this one";
}
open IN, '<', 'grep' or die 'dulce et decorum est';
open OUT, '>', 'gout' or die 'dulce et decorum est';
while (<>) {
print OUT if shift @prints
}
close IN;
close OUT;
__DATA__
1
3
5
8
Cheers, R.
Pereant, qui ante nos nostra dixerunt!
| [reply] [d/l] |