C-shell programming
Reiner Wilhelms
reiner at slithy-tove.shs.ohio-state.edu
Wed Aug 8 07:36:17 AEST 1990
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 at 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 at 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
More information about the Comp.unix.questions
mailing list