LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous messageNext messagePrevious in topicNext in topicPrevious by same authorNext by same authorPrevious page (April 2003, week 4)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
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
Comments: To: QYing <qiying.zhou@EQUIFAX.COM>
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;


Back to: Top of message | Previous page | Main SAS-L page