Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!tut.cis.ohio-state.edu!jabberwock.shs.ohio-state.edu!slithy-tove.shs.ohio-state.edu!reiner From: reiner@slithy-tove.shs.ohio-state.edu (Reiner Wilhelms) Newsgroups: comp.unix.questions Subject: Re: C-shell programming Summary: Reading multiple files in parallel from shell scripts: bourne and c-shell examples Keywords: csh, multiple file input Message-ID: <235@jabberwock.shs.ohio-state.edu> Date: 7 Aug 90 21:36:17 GMT References: <230@jabberwock.shs.ohio-state.edu> <3039@awdprime.UUCP> Sender: news@jabberwock.shs.ohio-state.edu Distribution: usa Lines: 139 Last week I asked for advise to write a C-shell script which is capable of reading from more than one file in parallel. I was lucky: two people (at least) came up with immediate answers. Thank you. Jeffrey Youngstrom (teda!jeffy@decwrl.dec.com ) had this piece of code designed for reading one file: #!/bin/csh -f # argument 1 ($1) is the input file name @ line=1 set length=`wc -l $1 | awk '{print $1}'` # find the number of lines # in the input file while ($line < $length) set stuff=`sed -n $line,${line}p $1` # do some stuff echo $stuff # increment the line count @ line++ end exit According to him, it is truely slow ("# disgustingly slow csh cat..."), and he is right. However, I am still very happy that someone found at least this solution, and it is useful because it can easily be extended to reading from several files in the same while loop, see below. Paul Chamberlain (tif@doorstop.austin.ibm.com)'s important hint is for Bourne shells, for which it is also not really obvious how to read several files in parallel. He wrote: > A bourne shell script could use the 3< 4< etc. syntax like this > > : > ( > read from_filename1 <&3 > read from_filename2 <&4 > read from_filename3 <&5 > echo to_filename_4 >&6 > ) 3< $1 4< $2 5< $3 6> $4 > > I haven't tried this but it's at least close. I don't think > csh has an equivalent feature...." > I agree, as far as I know, there is no real equivalent method in C-shells. With these two hints at hand I tinkered around and finally arrived at the following two shells which (at least for me) work. The files NN.dat1, NN.dat2, and NN.dat3 contain the lines printed below. We want to join them into the file NN.out, which is also printed below. :::::::::::::: NN.dat1 :::::::::::::: Joe 32 W Terry 40 V Michel 32 M Ute 28 K Reiner 37 G Uwe 32 D :::::::::::::: NN.dat2 :::::::::::::: Joe Chicago Terry Terry Cairo Michel Michel Haiti Ute Ute Berlin Reiner Reiner Columbus Uwe Uwe Berlin NIL :::::::::::::: NN.dat3 :::::::::::::: Joe 167 ++ Terry 180 * Michel 177 !! Ute 180 ?? Reiner 179 +- Uwe 178 @ :::::::::::::: NN.out (output file) :::::::::::::: Joe/32/W/Chicago.Terry.167.JJ Terry/40/V/Cairo.Michel.180.TM Michel/32/M/Haiti.Ute.177.MT Ute/28/K/Berlin.Reiner.180.UW Reiner/37/G/Columbus.Uwe.179.REW Uwe/32/D/Berlin.NIL.178.UWE :::::::::::::: Each script is called via % join_shell NN.dat1 NN.dat2 NN.dat3 NN.out The Bourne-script which does the job is this: #!/bin/sh rm -f $4 # remove old output file touch $4 # create new one ( i=0 while read name age code <&3 do read namex location follow <&4 read namex size symbol <&5 echo $name/$age/$code/$location.$follow.$size $symbol >&6 i=`expr $i + 1` done echo $i lines read ) 3<$1 4<$2 5<$3 6>$4 exit .. and the csh script which does the same job is here: #!/bin/csh -f @ line=1 rm -f $4 # remove old output file touch $4 # create a new one set length=`wc -l $1 | awk '{print $1}'` while ($line <= $length) set S=`sed -n ${line}p $1` set W=`sed -n ${line}p $2` set U=`sed -n ${line}p $3` echo $S[1]/$S[2]/$S[3]/$W[2].$W[3].$U[2].$U[3] >> $4 @ line++ end echo $length lines read exit Both are pretty slow. But I'm glad that they at least work. It looks simple, doesn't it. But it takes so much time to figure it out, that's why I still hate shell programming. Reiner