10-23-2017 11:46 AM
I'm reading a pipe delimited text file which has four fields per record with modified list input, and I want to somehow skip over the second and third field (which may be null). Is this possible?
1|ignore me|ignore me too|10 2|ignoreme||20 3|||30
I can get what I want if I include place holders on the input list for the fields I want to ignore, but it looks silly i.e.:
data want (drop=_: ); infile "d:\junk\dummy.txt" dlm="|" dsd ; input ID _Ignore1 : $1. _Ignore2 : $1. Value : 8. ; put (ID Value)(=); run;
I was thinking there might be a pointer control which instead of moving a certain number of column, moves a number of fields. Below pseudo-code:
data want ; infile "d:\junk\dummy.txt" dlm="|" dsd ; input ID +2col /*pseudo code: skip two fields*/ Value : 8. ; put (ID Value)(=); run;
Is there anything like that?
I can get what I want from by scanning _infile_, i.e.:
data want ; infile "d:\junk\dummy.txt" dlm="|" dsd ; input ID : 8. ; Value=input(scan(_infile_,4,"|","M"),8.); put (ID Value)(=); run;
But it seems like when you're doing list input (modified or not), it would be handy to have pointer controls that allow you to skip forward or backward by a number of fields, similar to pointer controls that move a number of columns.
Is there something like that? If not, is it a crazy idea? (I don't do a lot of reading of text files).
10-23-2017 12:25 PM - edited 10-23-2017 12:26 PM
I think CALL SCAN can get you there:
The idea would be along these lines:
input ID @ ;
Then use call scan ==> find the position of the third delimiter within _INFILE_ (or possibly the position of the fourth word), being careful to use the M option to treat consecutive delimiters as marking separate words
input @ location_returned_by_call_scan +1 value;
I trust you (as much as I trust myself, anyway) to fiddle with the options to get them working. For example, I'm not sure whether you really need to add +1 in the INPUT statement.
10-23-2017 12:41 PM
Not that it is elegant but you can reuse names on an input statement.
So if you are really really sure that you don't want fields 2 and 3 your example could be
_Ignore : $1.
_Ignore : $1.
Value : 8.
10-23-2017 03:05 PM
I think good programming practice would require that you read the fields into variables with descriptive names indicating what the fields are supposed to contain and then drop them.
Do what I say, not what I do...
10-24-2017 10:14 AM
Your first code is good enough. Why do you want more slick one ? Hope you would like the following code . data x; infile cards dsd dlm='|'; input @; _n_=findc(_infile_,'|','b'); input id @(_n_+1) score; cards; 1|ignore me|ignore me too|10 2|ignoreme||20 3|||30 ; run;