Date: Fri, 25 Apr 2003 09:32:42 +0000
Reply-To: Peter Crawford <peter.crawford@DB.COM>
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Peter Crawford <peter.crawford@DB.COM>
Subject: Re: Reading in variable length record with multiple segments in
one record
Content-Type: text/plain; charset="us-ascii"
This example was designed to show-off some more _infile_ magic
...that amazing flexibility sas data steps offer for reading data.
This data design could be read using the segId as delimiters, but
that makes collecting their values a more little difficult. In the
following data step, the infile buffer is updated by replacing
segId with a blank to be used as the infile delimiter. The
remaining characters are compressed out of a copy of the original
buffer to leave a convenient list of the segId (in variable buff2).
(Of course, it's possible to do this without DSD, but that has
(become an instinctive parameter I add to most infiles :-))
%let segs = ABCD ; * adapt as neccessary ;
data xx (keep = id segid content compress= char ) ;* /debug;
infile cards ls=32000 truncover dsd dlm=' ';
id = _n_;
length segId $1 content $ 200/*set content length, as neccessary*/
buffer $32000 buff2 $10000 ;
input @2 @ ; *position after the first segId;
buffer = _infile_ ;
_infile_ = translate( _infile_, " ", "&segs" ) ;
*replacing segId with blanks allows these to be delimiters
and is halfway to filling buff2 with only segId ;
buff2 = compress( buffer, _infile_ ); *keep just the segId;
segId = buff2 ; * first segId only;
do segNo = 1 to length(buff2) ;
input content @ ; * get content without segId;
content = segId !! content ; * ! put segId back ;
output ;
segId = substr( buff2, segNo+1 );
end;
cards;
A1234B123456B123456C1234567
A1234
A1234C1234567C1234567
;
Regards
Peter Crawford
author of sugi28 paper
More _Infile_ Magic
http://www2.sas.com/proceedings/sugi28/086-28.pdf
QYing <qiying.zhou@EQUIFAX.COM>
Sent by: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
24/04/03 20:12
Please respond to QYing
To: SAS-L@LISTSERV.UGA.EDU
cc:
Subject: Reading in variable length record with multiple segments in one record
Could someone please shed light on this problem I am trying to solve?
Thanks.
Ying
**************************************************************
Data in: (the real records are 1000+ to 7000+ bytes long)
A1234B123456B123456C1234567
A1234
A1234C1234567C1234567
etc
**************************************************************
Desired outcome:
id - segid - content
1 - A - A1234
1 - B - B123456
1 - B - B123456
1 - C - C1234567
2 - A - A1234
3 - A - A1234
3 - C - C1234567
3 - C - C1234567
*************************************************************
I tried the following idea and it went into loops.
*************************************************************
DATA test;
INFILE 'person.dat' lrecl=10000 truncover length = reclen recfm = v;
input @@;
loc = 1;
do while (loc < reclen );
INPUT @loc segid $1. @@;
if segid='A' then do;
loc=1;
INPUT @loc content $4. segid @;
loc+4;
end;
if segid='B' then do;
INPUT @loc content $6. segid @;
loc+6;
end;
if segid='C' then do;
INPUT @loc content $7. segid @;
loc+7;
end;
end;
RUN;
proc print;
run;