BookmarkSubscribeRSS Feed
Quentin
Super User

Hi All,

 

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?

 

Data like:

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).


Thanks!

4 REPLIES 4
Astounding
PROC Star

I think CALL SCAN can get you there:

 

http://documentation.sas.com/?docsetId=lefunctionsref&docsetTarget=n0ecxfx00bn8i4n1vhh8up24ha6x.htm&...

 

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.

 

Good luck.

ballardw
Super User

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

input ID
    _Ignore : $1.
    _Ignore : $1.
    Value   : 8.
  ;

 

drop _ignore;

PGStats
Opal | Level 21

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...

PG
Ksharp
Super User
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;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

Register Now

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 4 replies
  • 1567 views
  • 7 likes
  • 5 in conversation