Home > Archive > PERL Beginners > August 2007 > customizing eof chatacter
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
customizing eof chatacter
|
|
| Jorge Almeida 2007-08-05, 7:58 am |
| Is there some variable that will do for a file what $/ does for a
record?
What I mean is that in
$s=<STDIN>
the value of $s depends on the value of $/, but in
@arr=<STDIN>
I couldn't find a way to force the reading to stop when some character
is found.
Note that reading STDIN line by line and checking for a character won't
do the job, because somewhere in the program I need something like
open(F,"do-something|");
while(<F> ){...}
and later
open(G,"do-something-else|")
while(<G> ){...}
So, assuming that the program's standard input is redirected from some
file, I would need a way to divide the file into chunks, so that each
chunk would be treated as the whole STDIN each time @arr=<STDIN> or
open(F,"do-something|") appears in the program.
Any suggestion?
--
Jorge Almeida
| |
| Ken Foskey 2007-08-05, 7:00 pm |
| On Sun, 2007-08-05 at 13:21 +0100, Jorge Almeida wrote:
> Is there some variable that will do for a file what $/ does for a
> record?
> What I mean is that in
> $s=<STDIN>
> the value of $s depends on the value of $/, but in
> @arr=<STDIN>
You mention EOF and you mean EOL (end of line). Since you know the
correct variable you have read
perldoc perlvar
I am not the expert however I recall reading something about using local
I am guessing something like this:
sub myfunction
{
local $/ = "\r"; # I am a mac file!
my $input;
open( $input, '<', "MYMacFile.txt" )
or die "Unable to open MYMacFile.txt $!";
while( <$input> ) {
...
}
close( $input );
}
--
Ken Foskey
FOSS developer
| |
| Mumia W. 2007-08-05, 7:00 pm |
| On 08/05/2007 07:21 AM, Jorge Almeida wrote:
> Is there some variable that will do for a file what $/ does for a
> record?
> What I mean is that in
> $s=<STDIN>
> the value of $s depends on the value of $/, but in
> @arr=<STDIN>
> I couldn't find a way to force the reading to stop when some character
> is found.
> Note that reading STDIN line by line and checking for a character won't
> do the job, because somewhere in the program I need something like
> open(F,"do-something|");
> while(<F> ){...}
> and later
> open(G,"do-something-else|")
> while(<G> ){...}
> So, assuming that the program's standard input is redirected from some
> file, I would need a way to divide the file into chunks, so that each
> chunk would be treated as the whole STDIN each time @arr=<STDIN> or
> open(F,"do-something|") appears in the program.
> Any suggestion?
What do F and G have to do with STDIN?
The code "while(<F> ){...}" does not read from STDIN but from F.
There is no EOF character under Linux. Are you working under Windows?
| |
| John W. Krahn 2007-08-05, 7:00 pm |
| Jorge Almeida wrote:
> Is there some variable that will do for a file what $/ does for a
> record?
> What I mean is that in
> $s=<STDIN>
> the value of $s depends on the value of $/, but in
> @arr=<STDIN>
> I couldn't find a way to force the reading to stop when some character
> is found.
There is no "eof" character in modern operating systems, Back in the days of
CP/M (does anyone else here remember CP/M) they used an "eof" character
because the file system did not keep a record of file sizes so the only way to
determine if the file had ended was to assign a special character that marked
the file end. AFAIK all modern file systems store the file size so it is very
easy to determine when the end of the file is reached by keeping track of how
many bytes have been read.
In Unix (<Ctrl>-D) or in DOS/Windows (<Ctrl>-Z) the "eof" character is just a
signal to the terminal/console that there is no more data left and the actual
character is not included as a part of that data.
> Note that reading STDIN line by line and checking for a character won't
> do the job, because somewhere in the program I need something like
> open(F,"do-something|");
> while(<F> ){...}
> and later
> open(G,"do-something-else|")
> while(<G> ){...}
> So, assuming that the program's standard input is redirected from some
> file, I would need a way to divide the file into chunks, so that each
> chunk would be treated as the whole STDIN each time @arr=<STDIN> or
> open(F,"do-something|") appears in the program.
If you are redirecting input through a pipe there is no way to determine file
boundaries.
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
| |
| Jorge Almeida 2007-08-05, 7:00 pm |
| On Sun, 5 Aug 2007, Mumia W. wrote:
> On 08/05/2007 07:21 AM, Jorge Almeida wrote:
>
> What do F and G have to do with STDIN?
Everything...
>
> The code "while(<F> ){...}" does not read from STDIN but from F.
Of course.
>
> There is no EOF character under Linux.
OK, bad choice of words. What I wanted was to have "open" read some chunk
of stdin (treat it as if it were the whole thing), have the shell do its
job ("do-something") and then pipe the result to be read through the F
fh. Later, "open(G,..." would do something similar with _the next_ chunk
of input, and so on.
>Are you working under Windows?
Nope, I wouldn't touch Windows with a pole. But I should have mentioned
it...
>
--
Jorge Almeida
| |
| Jorge Almeida 2007-08-05, 7:00 pm |
| On Sun, 5 Aug 2007, John W. Krahn wrote:
> Jorge Almeida wrote:
>
>
>
>
> If you are redirecting input through a pipe there is no way to determine file
> boundaries.
>
OK, I suppose there is no way to do it...
I have an interactive, shell-like, program. Some commands read a line
from STDIN, or the whole STDIN (meaning until CTRL-D is pressed). Now I
want to modify the program to have a batch mode. Commands would be read
from STDIN (probably redirected from a file), as well as the data, if
any. The problem is how to keep the data for several commands in the
same file. One command would read a part of the data (as if it were the
whole input), the next command would read the next part, and so on. But
since some commands pass the input through the shell before using it, I
can't just read a chunk until some special character is found and call
it "the whole" stdin...
Impossible task, probably...
--
Jorge Almeida
| |
| Mr. Shawn H. Corey 2007-08-05, 7:00 pm |
| Jorge Almeida wrote:
> OK, I suppose there is no way to do it...
>
> I have an interactive, shell-like, program. Some commands read a line
> from STDIN, or the whole STDIN (meaning until CTRL-D is pressed). Now I
> want to modify the program to have a batch mode. Commands would be read
> from STDIN (probably redirected from a file), as well as the data, if
> any. The problem is how to keep the data for several commands in the
> same file. One command would read a part of the data (as if it were the
> whole input), the next command would read the next part, and so on. But
> since some commands pass the input through the shell before using it, I
> can't just read a chunk until some special character is found and call
> it "the whole" stdin...
> Impossible task, probably...
How big are these files? Could you read everything at once? If it's interactive, the user may choose different commands based on intermediate results, but if it's in batch mode, all the commands can be read at once; they won't change.
--
Just my 0.00000002 million dollars worth,
Shawn
"For the things we have to learn before we can do them, we learn by doing them."
Aristotle
| |
| Jorge Almeida 2007-08-05, 7:00 pm |
| On Sun, 5 Aug 2007, Mr. Shawn H. Corey wrote:
>
> How big are these files? Could you read everything at once? If it's
They're small enough to be slurped. The problem is that the chunk for a
particular command may need to be passed to the shell for processing
before being used by the Perl program. Something like this:
1 my @all=<STDIN>;
2 my @chunk=();
3 for (@all){
4 last if /^^D/;
5 push @chunk,$_;
6 }
7 open(H,"|grep-something-or-whatever|");# yes, I know this doesn't work!
8 for (@chunk){ print H $_;}
9 while(<H> ){
10 # do the real work now...
11 }
The problem, of course, starts with line 7...
I took a look at open(W,"|-") and open(R,"-|"). No good, the program is
too complex to deal gracefully with forking...
--
Jorge Almeida
| |
| Mr. Shawn H. Corey 2007-08-05, 7:00 pm |
| Jorge Almeida wrote:
> They're small enough to be slurped. The problem is that the chunk for a
> particular command may need to be passed to the shell for processing
> before being used by the Perl program. Something like this:
> 1 my @all=<STDIN>;
> 2 my @chunk=();
> 3 for (@all){
> 4 last if /^^D/;
> 5 push @chunk,$_;
> 6 }
> 7 open(H,"|grep-something-or-whatever|");# yes, I know this
> doesn't work!
> 8 for (@chunk){ print H $_;}
> 9 while(<H> ){
> 10 # do the real work now...
> 11 }
> The problem, of course, starts with line 7...
> I took a look at open(W,"|-") and open(R,"-|"). No good, the program is
> too complex to deal gracefully with forking...
>
See `perldoc perlfaq8` and search for "How can I open a pipe both to and from a command?"
--
Just my 0.00000002 million dollars worth,
Shawn
"For the things we have to learn before we can do them, we learn by doing them."
Aristotle
| |
| Jorge Almeida 2007-08-05, 7:00 pm |
| On Sun, 5 Aug 2007, Mr. Shawn H. Corey wrote:
>
> See `perldoc perlfaq8` and search for "How can I open a pipe both to and from
> a command?"
>
Thank you. I'll have to decide whether using IPC::Open2 is safe
enough...
--
Jorge Almeida
| |
| Ken Foskey 2007-08-06, 6:59 pm |
| On Sun, 2007-08-05 at 18:26 +0100, Jorge Almeida wrote:
> I have an interactive, shell-like, program. Some commands read a line
> from STDIN, or the whole STDIN (meaning until CTRL-D is pressed). Now I
> want to modify the program to have a batch mode. Commands would be read
> from STDIN (probably redirected from a file), as well as the data, if
> any. The problem is how to keep the data for several commands in the
> same file. One command would read a part of the data (as if it were the
> whole input), the next command would read the next part, and so on. But
> since some commands pass the input through the shell before using it, I
> can't just read a chunk until some special character is found and call
> it "the whole" stdin...
> Impossible task, probably...
It sounds like you want something similar to parameter handling,
generally this works on escalating files. eg /etc/myprog overridden by
~/.myprog overrridden by a specific options file and so on.
The trick is simply to read them in that order and then just use what is
left. So if /etc/myprog sets key X and ~/.myprog changes key X to some
other value then the last one to change wins. You just have to set them
up in the right order and it is not that hard.
--
Ken Foskey
FOSS developer
| |
| Jorge Almeida 2007-08-06, 6:59 pm |
| On Mon, 6 Aug 2007, Ken Foskey wrote:
> On Sun, 2007-08-05 at 18:26 +0100, Jorge Almeida wrote:
>
>
> It sounds like you want something similar to parameter handling,
> generally this works on escalating files. eg /etc/myprog overridden by
> ~/.myprog overrridden by a specific options file and so on.
>
> The trick is simply to read them in that order and then just use what is
> left. So if /etc/myprog sets key X and ~/.myprog changes key X to some
> other value then the last one to change wins. You just have to set them
> up in the right order and it is not that hard.
>
I suppose I can split the input file into several temporary files and
then redirect the input for each command to the appropriate file. I was
hoping for something cleaner, though.
Thanks.
--
Jorge Almeida
|
|
|
|
|