BookmarkSubscribeRSS Feed
FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Hi Folks,

I am trying to generate a SAS Data Set out of the DeploymentRegistry.txt (see: https://support.sas.com/kb/35/968.html ). Basicyally, this is a text file which lists for each product component of your SAS installation several information bits (like version, display name, applied hot fixes, etc.). 

 

So far I have this code

data test;

length Host $5. ;
length Product $15.; 
length Version $10.;
length Display_Name $100.;
length Display_Version $10.;


infile _tst truncover;
input;

len= length(_infile_);

if _infile_ =: "           Host" then
      Host = scan(_infile_,2,":") ;
if _infile_ =: "        Product" then 
		Product = scan(_infile_,2,":");
if _infile_ =: "        Version" then 
		Version = scan(_infile_,2,":");
if _infile_ =: "   Display Name" then 
		Display_Name = scan(_infile_,2,":");
if _infile_ =: "Display Version" then 
		Display_Version = scan(_infile_,2,":");


if length(_infile_) < 2 then delete;

run;

But this produces multiple lines for each product component which I want in one line.

So instead of this:

have.JPG

 

I want this:

want.JPG

 

Any hints as In which way I'd have to modify my code?

Maybe use the retain statement???

Cheers,

FK1

3 REPLIES 3
AMSAS
SAS Super FREQ

This code does something similar although it outputs to the SAS log 

options nomprint nomprintnest nomlogic nomlogicnest nosymbolgen nosource nosource2; 

/* Parse Registry File */
/* v0.1 */
/* Andy.Mayes@SAS.COM */
/* Feb 2021 */

/* Updates */
/* 17FEB2021 deculp Traverse directory and parse each registry file in the directory */
/* 18Feb2021 snzroo Merged my changes to Dereks and formatted output example:
		*******************************************************************************
		Filename 1: Meta-DeploymentRegistry.txt
		*******************************************************************************
		===============
		HOT FIX SUMMARY
		Meta-DeploymentRegistry.txt
		===============
		SAS Thread-safe Compiler and Symbolic Differentiator                      9.57
		SAS Model Implementation Platform Server Configuration                    3.2
		SAS High-Performance Risk Server Component                                4.2       F7P004
		===============

		*******************************************************************************
		Filename 2: Mid-DeploymentRegistry.txt
		*******************************************************************************

		===============
		HOT FIX SUMMARY
		Mid-DeploymentRegistry.txt
		===============
		SAS Infrastructure for Risk Management Mid-Tier                           3.6
		SAS Thread-safe Compiler and Symbolic Differentiator                      9.57
		SAS Risk and Finance Workbench Mid-Tier                                   3.2       D4N006
		=============== */
/* 22Feb2021 snzroo Small changes to improve output, and restrict to files with a specific externsion */

/* 04Mar2021 snzroo RegistryParser_rev04.sas
             Added file match set fileMatch macro variable to PERL Regular Expression
             Only processes files that match the expression
             This allows code to run against directory with multiple files and only 
             report on required registry reports e.g. 
             FileMatch=DeploymentRegistry\.txt
             Will only analyse files that have DeploymentRegistry.txt in their file name
             EXT macro no longer required 
*/

/* 20Apr2021 snzroo RegistryParser_rev05.sas
             Fixed warning message 
*/

/* 19Jul2022 snzroo RegistryParser_rev06.sas
             Removed the need to define the ext macro variable 
             Now code pulls the file extenstion (ext) from the fileMatch
*/


/* Instructions */
/* 1. Set VRDIR to the directory that contains the ViewRegistry Reports */
/* 2. Set EXPR to the SAS components to find and report using a PERL Regular Expression */
/* 3. DELETE - Set EXT to the file extension you want to interrogate */
/* 3. Set fileMatch to a regular expression to find matching files */
/* 4. Submit program, and view results in the SAS log */


%let vrdir = <Change this> ;
/* SNZROO 2022-07-19 Start */
/* Remove the need to define the ext macro */

/* %let ext   = txt; /**/
/* SNZROO 2022-07-19 End */

/* 
	fileMatch = DeploymentRegistry.*\.txt 
		Searches for any file "DeploymentRegistry<other characters>.txt"
*/
%let fileMatch = .*DeploymentRegistry.*\.txt* ;

/* %let expr  = modimp|modimpsvr|modimpmiddoc|modimpmid|modimpsvrc|modimpsvr; /**/
%let rfw   = stresssvr|stressmid|ssrsvr|ssrsvrc|stressmid; /* RFW */
%let irm   = rmifirmmvac|riskminmid|rmifirmmva; /* IRM 3.6 */
%let cmp   = cmp|tkcmp ; /* SAS (Thread-safe) Compiler and Symbolic Differentiator */
%let hpr   = hprisksvr|riskcmnmid|hpriskmid|risk|rskwkgpmid ; /* HPRISK */
%let mip   = modimpmid|modimpsvr|riskmodedmid ;    /* MIP */
%let rgf   = rskmgtsvr|rgpmid|rgpadm ;
             
%let expr  = base|hprisksvr|risk|hpriskmid|modimp|cmp|tkcmp|stressmid|stresssvrc|stresssvr|modimpsvr|modimpmiddoc|modimpmid|modimpsvrc|modimpsvr; /**/
%let expr  = &hpr|&mip ; 
* options mlogic mprint symbolgen ;
%macro list_hot_fixes(dir,fname,expr);
  filename regfile "&dir.\&fname.";

  data readReg;
  	file="&fname" ;
    reProduct = prxparse("/Product: (&expr.)/");
	reDisplayName = prxparse("/Display Name:/") ;
	deDisplayName = prxparse("s/Display Name://") ;
	reVersion     = prxparse("/Version:/") ;
	deVersion     = prxparse("s/(Version:)|(Display Version:)//") ;
	*deVersion     = prxparse("s/Version://") ;
	reHotFixEntry = prxparse("/Hot Fix Entry: Hotfix/") ;
	deHotFixEntry = prxparse("s/Hot Fix Entry: Hotfix//") ;

    infile regfile;
    input;
    /* Scan for Product */
    *if findw(_infile_,"risk") then do ;
    if prxmatch(reProduct,_infile_) then do;
      * put "PRODUCT : " _infile_;
      /* Repeat until end of Product */
      hotFixFound=0;
      do until(findw(_infile_,"-----"));
        input;
        * put _infile_;
		if prxmatch(reDisplayName,_infile_) then do ;
			displayname=prxchange(deDisplayName,1,_infile_) ;
			* put "Display Name: " _infile_ ;
		end ;
		else if prxmatch(reVersion,_infile_) then do ;
			version=prxchange(deVersion,1,_infile_) ;
			* put "VERSION : " _infile_ ;
		end ;
		else if prxmatch(reHotFixEntry,_infile_) then do ;
			* put "HOT FIX : " _infile_ ;
			hotFixFound=1 ;
			hotFix=prxchange(deHotFixEntry,1,_infile_) ;
			output ;
		end ;

		end ;
		if hotFixFound=0 then
			output ;
	end ;
	
run ;
  /* Pull version */
  /* Pull Hot Fixes */ 
proc sort data=readreg out=srtdReg ;
	by displayname ;
run ;
 data _null_ ;
	set srtdReg;
	by displayname ;
	if last.displayname then
		put displayname @75 version @85 hotfix ;

run ;
%mend list_hot_fixes;


%macro get_viewregistry_files(fr,dir,type);
  %global nfiles;

  proc sql noprint;
    /*  Get number of files  */
    select count(fname) into : nfiles
        from work.vrfiles
		;
    %let nfiles=%trim(%left(&nfiles));

    /*  Assign each filename to a macro variable  */
    %do zz=1 %to &nfiles;
      %global fname&zz;
      %global ext&zz;
    %end;
    select fname into : fname1 - : fname%trim(&nfiles)
        from work.vrfiles
		;
    select ext into : ext1 - : ext%trim(&nfiles)
        from work.vrfiles
		;
  quit;
  %do i=1 %to &nfiles ;
  	%put DEBUG - &&fname&i ;
  %end ;
%mend get_viewregistry_files;

%macro list_hfs_by_vrfile(fileref,type);
  /* For each ViewRegistry Report, list the release details for the relevant components */
  %get_viewregistry_files(&fileref,&vrdir,&type);
  options nosymbolgen nonotes nomprint nomprintnest nomlogic nomlogicnest nosource nosource2; 
  /* dm 'clear log'; SNZROO 04/07/21 commenting this out, as I want to see the full log */
  %put ;
  %put ;
  %put List of files in: &vrdir;
  %put ;
  %put   With ViewRegistry details where:;
  %put     File extension is:           &type;
  %put     And hot fix component is in: &expr;
  %put ;
  %put ; 
  %do ii = 1 %to &nfiles;
    %put ;
    %put ;
    %put *******************************************************************************;
    %put Filename &&ii: &&fname&ii;
    %put *******************************************************************************;
    %put ;
/*    %if %UPCASE(&&ext&ii)=%UPCASE(&type) %then %do; */
      %list_hot_fixes(&vrdir,&&fname&ii,&expr);
/*    %end; */
  %end;
%mend list_hfs_by_vrfile;

/* Store each filename in the ViewRegistry directory in a SAS data set */
filename v "&vrdir";
data work.vrfiles (keep=fname ext);
  reFileMatch = prxparse("/&FileMatch./");

  did=dopen("v");
  filecount=dnum(did);
  do i=1 to filecount;
    fname=dread(did,i);
	put fname= ;
    ext=trim(scan(fname,-1,".","r"));
    lext=length(ext);
    lfil=length(fname);
	/* SNZROO 2022-07-19 Start */
	/* Remove the need to define the ext macro */
	call symput("ext",ext) ;
	/* SNZROO 2022-07-19 End  */

    /*file=substr(fname,1,lfil-lext-1);*/
	/*if ext="&ext" then */
	if prxmatch(reFileMatch,fname) then 
    	output;
  end;
  rc=dclose(did);
run;

%list_hfs_by_vrfile(v,&ext);
ballardw
Super User

RETAIN the values of variables. That will keep values across iterations of the data step boundary.

Then when you get to the last item use an explicit OUTPUT call to write to the data set then reset the retained values to missing after writing to the set . When you have an explicit OUTPUT (or multiple) that is the only time the data gets written to the output set.

Call Missing is the easiest way to set a bunch of  variables to missing as that is what is designed to do.

 

data test;

length Host $5. ;
length Product $15.; 
length Version $10.;
length Display_Name $100.;
length Display_Version $10.;
Retain Host product version display_name display_version;

infile _tst truncover;
input;

len= length(_infile_);

if _infile_ =: "           Host" then
      Host = scan(_infile_,2,":") ;
if _infile_ =: "        Product" then 
		Product = scan(_infile_,2,":");
if _infile_ =: "        Version" then 
		Version = scan(_infile_,2,":");
if _infile_ =: "   Display Name" then 
		Display_Name = scan(_infile_,2,":");
if _infile_ =: "Display Version" then 
		Display_Version = scan(_infile_,2,":");

if not missing(display_version) then output;
call missing(Host, product, version, display_name, display_version); if length(_infile_) < 2 then delete; run;

 

FK1
Lapis Lazuli | Level 10 FK1
Lapis Lazuli | Level 10

Hey everyone,

thank's a lot for all your helpful advice.

I finally came up with this, which works in 99% of the cases, where there are not hot fixes:

 


%LET SLSH = %qsysfunc(ifc(%UPCASE(&SYSSCP) = WIN,\,/));
%*PUT &=SLSH;

** get location of SAS installation:  **;
%LET SASROOT = %SYSGET(SASROOT);
%*PUT &=SASROOT;

** get SASHOME level for applications and such **;
%LET SASHOME = %SYSGET(SASHOME);
%*PUT &=SASHOME;

** Temporary Folder for registry report files **;
%LET _regrepfolder = %SYSFUNC(pathname(WORK))&SLSH.REPSTUFF;
%PUT &=_regrepfolder;


/*Allocate temporary file for Output of Registry Report in subfolder of WORK-path*/
option DLCREATEDIR;

LIBNAME _regrep "&_regrepfolder.";

/*Generate fresh registry report (see: https://support.sas.com/kb/35/968.html)*/
data _NULL_;
call system("&SASHOME&SLSH.SASPrivateJavaRuntimeEnvironment&SLSH.9.4&SLSH.jre&SLSH.bin&SLSH.java -jar &SASHOME&SLSH.deploymntreg&SLSH.sas.tools.viewregistry.jar -out &_regrepfolder." );
run;


filename regfile "&_regrepfolder.&SLSH.DeploymentRegistry.txt";


  data readReg (drop=_numeric_);
    reHost        = prxparse("/Host:/");
	deHost        = prxparse("s/Host://");

    reProduct     = prxparse("/Product:/");
	deProduct     = prxparse("s/Product://");

	reVersion     = prxparse("/Version:/") ;
	deVersion     = prxparse("s/Version://") ;
/*
	reVersion     = prxparse("/Version:/") ;
	deVersion     = prxparse("s/(Version:)|(Display Version:)//") ;
*/
	reDisplayName = prxparse("/Display Name:/") ;
	deDisplayName = prxparse("s/Display Name://") ;

	reHotFixEntry = prxparse("/Hot Fix Entry: Hotfix/") ;
	deHotFixEntry = prxparse("s/Hot Fix Entry: Hotfix//") ;

    reDisplayVersion = prxparse("/Display Version:/") ;
	deDisplayVersion = prxparse("s/Display Version://") ;


    infile regfile;
    input;

    /* Scan for Product */

    if prxmatch(reHost,_infile_) then do;
	    host=prxchange(deHost,1,_infile_) ;
      * put "PRODUCT : " _infile_;
      /* Repeat until end of Product */
      hotFixFound=0;


      do until(findw(_infile_,"-----"));
        input;
        * put _infile_;
		if prxmatch(reDisplayName,_infile_) then do ;
			displayname=strip(prxchange(deDisplayName,1,_infile_)) ;
			* put "Display Name: " _infile_ ;
		end ;
		else if prxmatch(reDisplayVersion,_infile_) then do ;
			displayversion=strip(prxchange(deDisplayVersion,1,_infile_)) ;
			* put "Display Version: " _infile_ ;
		end ;
		else if prxmatch(reProduct,_infile_) then do ;
					product=strip(prxchange(deProduct,1,_infile_)) ;
		end;
		else if prxmatch(reVersion,_infile_) then do ;
			version=strip(prxchange(deVersion,1,_infile_)) ;
			* put "VERSION : " _infile_ ;
		end ;
		else if prxmatch(reHotFixEntry,_infile_) then do ;
			* put "HOT FIX : " _infile_ ;
			hotFixFound=1 ;
			hotFix=strip(prxchange(deHotFixEntry,1,_infile_)) ;
			output ;
		end ;

			end ;

		if hotFixFound=0 then output ;
	end ;
	
run ;

Only problem left: in case a product has a hot fix, then the respective line does not have a value for "displayname" even though in the registry file there is one:

hf_linse.JPG

 

Has anybody an idea how to fix this issue?

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 654 views
  • 2 likes
  • 3 in conversation