BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
khandelwalanmol
Fluorite | Level 6

I have txt response header file created out of proc http . i need to read in status code and a url from the response file to create global macrovaribales.

Here is my txt file: 

HTTP/1.1 202 Accepted
Content-Length: 0
Cache-Control: no-cache; no-store; must-revalidate; max-age=0
Content-Location: https://testapi.gov.in/api/v1/jobs/4648
Pragma: no-cache
Date: Fri, 16 Apr 2021 10:58:50 GMT
Connection: keep-alive
Strict-Transport-Security: max-age=86400
X-Content-Type-Options: nosniff

I need to create macro variable of the status code from 1st line and URL from the 4th line.

Till now i was just reading in the code using this: 

filename header "/test/api/exec_job_head.txt";
data test; infile header dlm='09'x; length header_col $100.; input header_col ; run;

 

Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Why did you use tab as the delimiter on the INFILE statement?  Are you sure the file has tabs (or are you sure the file does NOT have tabs)?

Also are you sure the file will have line breaks? Many "response" files are sent without any line breaks.

Let's convert your posting into an actual file:

options parmcards=header ;
filename header temp;

parmcards4;
HTTP/1.1 202 Accepted
Content-Length: 0
Cache-Control: no-cache; no-store; must-revalidate; max-age=0
Content-Location: https://testapi.gov.in/api/v1/jobs/4648
Pragma: no-cache
Date: Fri, 16 Apr 2021 10:58:50 GMT
Connection: keep-alive
Strict-Transport-Security: max-age=86400
X-Content-Type-Options: nosniff
;;;;

Please show what output you expect to get from that example input.  What part of that is the STATUS? The URL?

 

To be more robust you probably want to test what the line LOOKS like rather than its position.

Assuming the file actually has line breaks you might use something like this:

data want;
  do row=1 by 1 until (eof);
    infile header truncover end=eof;
    input @;
    if row=1 then input status $100. ;
    else if _infile_=:'Content-Location:' then input @':' url $200. ;
    else input;
  end;
run;

Result

Obs    row           status                              url

 1      9     HTTP/1.1 202 Accepted    https://testapi.gov.in/api/v1/jobs/4648

 It might just be easier to read the file as NAME/VALUE pairs.

data headers ;
  infile header dlm=':' truncover ;
  length field $100 value $200 ;
  if _n_=1 then do;
    field='Status'; input value $200.;
  end;
  else input field value $200.;
run;

Results:

Obs    field                        value

 1     Status                       HTTP/1.1 202 Accepted
 2     Content-Length               0
 3     Cache-Control                no-cache; no-store; must-revalidate; max-age=0
 4     Content-Location             https://testapi.gov.in/api/v1/jobs/4648
 5     Pragma                       no-cache
 6     Date                         Fri, 16 Apr 2021 10:58:50 GMT
 7     Connection                   keep-alive
 8     Strict-Transport-Security    max-age=86400
 9     X-Content-Type-Options       nosniff

View solution in original post

3 REPLIES 3
Astounding
PROC Star

You can save half the work by using ODS.  Whatever you see as a header file can be captured as a SAS data set using ODS.  You would need to run the PROC after adding:

 

ODS TRACE ON;

 

That will reveal the names of the outputs that are available as data sets.  Once you know the names, you can add an ODS SELECT statement to capture that as a SAS data set.

 

Do you know how to take a variable in a SAS data set and transfer it to a macro variable?

RichardDeVen
Barite | Level 11

The status code will always be in the first line, but the url might possibly be in lines different than the 4th.

 

You can use SCAN function to extract relevant portions and SYMPUT to move the value from the DATA Step to the macro environment.  Because the operation is for only populating macro variables no output data set need be created, hence DATA _NULL_.

 

Example:

 

filename header "/test/api/exec_job_head.txt";
data _null_;
   infile header;
   input;  /* fill automatic _infile_ variable with entire line */
   if _n_ = 1 then do;
     call symput ('status', scan(_infile_,2,'0920'x)); /* extract 2nd item allowing for both tab and space optional whitespace */
   end;
   else
   if upcase(_infile_) = 'CONTENT-LOCATION:' then do;
     place = index (_infile_, ':');
     call symput('URL', strip(substr(_infile_, place+1)));
     stop;
   end;
run;

 

Tom
Super User Tom
Super User

Why did you use tab as the delimiter on the INFILE statement?  Are you sure the file has tabs (or are you sure the file does NOT have tabs)?

Also are you sure the file will have line breaks? Many "response" files are sent without any line breaks.

Let's convert your posting into an actual file:

options parmcards=header ;
filename header temp;

parmcards4;
HTTP/1.1 202 Accepted
Content-Length: 0
Cache-Control: no-cache; no-store; must-revalidate; max-age=0
Content-Location: https://testapi.gov.in/api/v1/jobs/4648
Pragma: no-cache
Date: Fri, 16 Apr 2021 10:58:50 GMT
Connection: keep-alive
Strict-Transport-Security: max-age=86400
X-Content-Type-Options: nosniff
;;;;

Please show what output you expect to get from that example input.  What part of that is the STATUS? The URL?

 

To be more robust you probably want to test what the line LOOKS like rather than its position.

Assuming the file actually has line breaks you might use something like this:

data want;
  do row=1 by 1 until (eof);
    infile header truncover end=eof;
    input @;
    if row=1 then input status $100. ;
    else if _infile_=:'Content-Location:' then input @':' url $200. ;
    else input;
  end;
run;

Result

Obs    row           status                              url

 1      9     HTTP/1.1 202 Accepted    https://testapi.gov.in/api/v1/jobs/4648

 It might just be easier to read the file as NAME/VALUE pairs.

data headers ;
  infile header dlm=':' truncover ;
  length field $100 value $200 ;
  if _n_=1 then do;
    field='Status'; input value $200.;
  end;
  else input field value $200.;
run;

Results:

Obs    field                        value

 1     Status                       HTTP/1.1 202 Accepted
 2     Content-Length               0
 3     Cache-Control                no-cache; no-store; must-revalidate; max-age=0
 4     Content-Location             https://testapi.gov.in/api/v1/jobs/4648
 5     Pragma                       no-cache
 6     Date                         Fri, 16 Apr 2021 10:58:50 GMT
 7     Connection                   keep-alive
 8     Strict-Transport-Security    max-age=86400
 9     X-Content-Type-Options       nosniff

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 3 replies
  • 1435 views
  • 3 likes
  • 4 in conversation