[comp.unix.shell] How to read sequentially from a file in SH

afc@shibaya.lonestar.org (Augustine Cano) (04/27/91)

KSH can handle reading from a file sequentially with no problem if
one uses the following statements:

exec 3< $FILENAME

while read -u3 VAR1 VAR2; do
  print $VAR1 $VAR2
done

SH does not support this (at least not the one I have).  I have tried:

while read VAR1 VAR2 < $FILENAME; do
  echo $VAR1 $VAR2
done

but I keep reading the first line in the file over and over.  Nothing in
the manual page seems to be usable in this situation.  How is this done
under SH?  Is it possible?  Using ksh is not an option since the machine
I need to run this on does not have it.

Thanks in advance.  I'll summarize e-mailed responses.
-- 
Augustine Cano		INTERNET: afc@shibaya.lonestar.org
			UUCP:     ...!{ernest,egsner}!shibaya!afc

mcgough@wrdis01.af.mil (Jeffrey B. McGough) (04/28/91)

In article <1991Apr27.012336.2732@shibaya.lonestar.org> afc@shibaya.lonestar.org (Augustine Cano) writes:
>SH does not support this (at least not the one I have).  I have tried:
>
>while read VAR1 VAR2 < $FILENAME; do
>  echo $VAR1 $VAR2
>done

This can be done by...

#! /bin/sh

FILENAME="/foo/bar"

while read VAR1 VAR2
do
{
	echo "$VAR1 VAR2"
}
done < "$FILENAME"

Hope this helps... 
The double quotes are my version of paranoia

I user stuff like this for various admin
tasks all the time...


-- 
Lator,                                       We cheat the other guy,
                                             and pass the savings on to you.
Jeffrey B. McGough
WR-ALC UNIX Systems Administrator                    (mcgough@wrdis01.af.mil)

cpcahil@virtech.uucp (Conor P. Cahill) (04/28/91)

afc@shibaya.lonestar.org (Augustine Cano) writes:

>while read VAR1 VAR2 < $FILENAME; do
>  echo $VAR1 $VAR2
>done

use:

	while read VAR1 VAR2; do
		echo $VAR1 $VAR2
	done < $FILENAME

or:
	cat $FILENAME |
	while read VAR1 VAR2; do
		echo $VAR1 $VAR2
	done

>but I keep reading the first line in the file over and over.  Nothing in

This is because the shell kept reopening the file every time it went to 
execute the read.

-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

mike@bria.UUCP (Michael Stefanik) (04/28/91)

In an article, afc@shibaya.lonestar.org (Augustine Cano) writes:
|
|while read VAR1 VAR2 < $FILENAME; do
|  echo $VAR1 $VAR2
|done
|
|but I keep reading the first line in the file over and over.  Nothing in
|the manual page seems to be usable in this situation.  How is this done
|under SH?  Is it possible? 

cat $FILENAME | while read VAR1 VAR2
do echo $VAR1 $VAR2
done

-- 
Michael Stefanik, MGI Inc, Los Angeles | Opinions stated are never realistic
Title of the week: Systems Engineer    | UUCP: ...!uunet!bria!mike
-------------------------------------------------------------------------------
If MS-DOS didn't exist, who would UNIX programmers have to make fun of?

mark@spider.co.uk (Mark Valentine) (04/29/91)

afc> while read VAR1 VAR2 < $FILENAME; do
afc>   echo $VAR1 $VAR2
afc> done
afc>
afc> but I keep reading the first line in the file over and over.  Nothing in
afc> the manual page seems to be usable in this situation.  How is this done
afc> under SH?  Is it possible?

mike> cat $FILENAME | while read VAR1 VAR2
mike> do echo $VAR1 $VAR2
mike> done

Sometimes this doesn't fit into the logic of a shell script.  In such cases
I find that something like following works nicely.

    exec 3< $FILENAME
    while read VAR1 VAR2 <&3
    do echo $VAR1 $VAR2
    done

This is especially handy if you have a couple of files you're reading
simultaneously in the body of the loop, or the conditional isn't based
on the read itself.

		Mark.
-- 
Mark Valentine, Spider Systems <mark@spider.co.uk>            /\oo/\

smk@cbnews.cb.att.com (stephen.m.kennedy) (04/29/91)

>In an article, afc@shibaya.lonestar.org (Augustine Cano) writes:
>
>while read VAR1 VAR2 < $FILENAME; do
>  echo $VAR1 $VAR2
>done
>
>but I keep reading the first line in the file over and over.  Nothing in
>the manual page seems to be usable in this situation.  How is this done
>under SH?  Is it possible? 

How about:

exec 3<$FILENAME
while read VAR1 VAR2 0<&3; do
  echo $VAR1 $VAR2
done
exec 3<&-
# any variable set in while loop will still be set here
# ...


or:

readit()
{
    while read VAR1 VAR2; do
        echo $VAR1 $VAR2
    done
}

readit <$FILENAME

Steve Kennedy
smk@cbosgd.att.com

dattier@vpnet.chi.il.us (David W. Tamkin) (05/01/91)

mark@spider.co.uk (Mark Valentine) wrote in
<1991Apr29.105329.20148@spider.co.uk>, quoting two other people:

| afc> while read VAR1 VAR2 < $FILENAME; do
| afc>   echo $VAR1 $VAR2
| afc> done
| afc>
| afc> but I keep reading the first line in the file over and over.  Nothing in
| afc> the manual page seems to be usable in this situation.  How is this done
| afc> under SH?  Is it possible?

| mike> cat $FILENAME | while read VAR1 VAR2
| mike> do echo $VAR1 $VAR2
| mike> done

Mike was onto it, but the extra fork for cat is unnecessary:

while read VAR1 VAR2
do echo $VAR1 $VAR2
done < $FILENAME

The trick is to redirect the entire loop and not just the read command.
Mark Valentine's suggested solution is not needed for this simple case.

David Tamkin  PO Box 7002  Des Plaines IL  60018-7002  dattier@vpnet.chi.il.us
GEnie:D.W.TAMKIN  CIS:73720,1570  MCIMail:426-1818  708 518 6769  312 693 0591