<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: scan multiple files and write list of file name in which contain error in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/450259#M113377</link>
    <description>&lt;P&gt;Hi.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Interesting - It Works fine for me.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Try to insert a&lt;U&gt; put rec $char200.;&lt;/U&gt;&amp;nbsp;statement after the Input statement,&amp;nbsp;It lists all input lines in the log, so you can see the lines that goes into the rest of the code. If you don't get the files listed, then something is wrong with the DIR command, otherwise it should be possible to see where the problem occurs. Use similar put- statements to see whether&amp;nbsp;the if-constructs become true and what you get there.&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Sun, 01 Apr 2018 18:27:05 GMT</pubDate>
    <dc:creator>ErikLund_Jensen</dc:creator>
    <dc:date>2018-04-01T18:27:05Z</dc:date>
    <item>
      <title>scan multiple files and write list of file name in which contain error</title>
      <link>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/449720#M113229</link>
      <description>&lt;P&gt;I have several SAS generated log files in c:\temp i.e. test1.log test2.log... I&amp;nbsp;need a program that&amp;nbsp;reads each&amp;nbsp;log and&amp;nbsp;writes to a SINGLE text file if the&amp;nbsp;log contains patter ERROR:. the code I have can give me a list of log name in&amp;nbsp;log window&amp;nbsp;without format. Is there better way to generate a text file and format better?&lt;/P&gt;&lt;PRE&gt;%let path=c:\temp;
filename dirlist pipe 'dir "c:\temp" /s';
data dirlist ;
     length logname outname $100;
	 retain cnt;
     infile dirlist length=reclen ;
	 input buffer $varying256. reclen ;
	 
	 if index(buffer, ".log") gt 0 then do;
	 	cnt+1;
		call symput('totallog',cnt);
	 	logname ="&amp;amp;path\"||strip(scan( buffer, -1, ' ' ));
		s1=scan(logname, -1, '\');
  		outname=scan(s1, 1, '.');
		output;
	end;
	keep logname outname;
run ;

%put &amp;amp;totallog;
%let cnt=&amp;amp;totallog;

proc sql noprint; select logname, outname into 	:log1-:log&amp;amp;cnt, :out1-:out&amp;amp;cnt from dirlist; quit;  


%macro read;
%do i=1 %to &amp;amp;totallog;
	data out_&amp;amp;&amp;amp;out&amp;amp;i; 
	 	 infile "&amp;amp;&amp;amp;log&amp;amp;i" lrecl=40 pad;
	 	 input @1 line $; 
		 if  upcase(substr(left(line),1,6))='ERROR:' then output;
	run;

	proc sql noprint; select line from out_&amp;amp;&amp;amp;out&amp;amp;i; quit; 
	%if &amp;amp;sqlobs gt 0 %then %do;
		%let all=&amp;amp;all. out_&amp;amp;&amp;amp;out&amp;amp;i;
	%end;
%end;
%mend;

%let all=;  %put &amp;amp;all;
%read;
%put ***********Error files: &amp;amp;all***********;&lt;/PRE&gt;</description>
      <pubDate>Thu, 29 Mar 2018 16:31:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/449720#M113229</guid>
      <dc:creator>nnl3256</dc:creator>
      <dc:date>2018-03-29T16:31:14Z</dc:date>
    </item>
    <item>
      <title>Re: scan multiple files and write list of file name in which contain error</title>
      <link>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/449745#M113242</link>
      <description>&lt;P&gt;Hi&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I will suggest a different approach&amp;nbsp;with a loop over a data set with file names. I have made an example based on code I am using. For each log file, the erroneus records are appended to the output file using the MOD file option.&amp;nbsp;The&amp;nbsp;code will not find all errors, because some sas errors are reported in the format ERROR 3-20: or some other number. So using&amp;nbsp;prxmatch with a suitable pattern will find all errors. I will be happy to&amp;nbsp;ansver further questions.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let path=e:\logs\batchjobs;
%let outfile = e:\work\errorlist.txt;
filename dirlist pipe "dir ""&amp;amp;path"" /s";

%let filesfound = 0;
data dirlist (drop=rec folder file filesfound);  	
	length fullfilename folder file $255;
	retain folder;
	infile dirlist truncover end=eof;
	input rec $char300.;
	if left(rec) =: 'Directory of ' then folder = substr(rec,15);
	else if substr(rec,1,1) ne '' then do;
		file = substr(rec,37);
			if file not in ('.','..') then do;
			fullfilename = trim(folder)||'\'||substr(rec,37);
			filesfound + 1;
			output;
		end;
	end;
	if eof then call symputx('filesfound',filesfound);
run;
%put &amp;amp;=filesfound;

%macro read;
	%if &amp;amp;filesfound &amp;gt; 0 %then %do;

		* Get max filename length for formatting output;
		proc sql noprint;
			select max(length(fullfilename))  into :maxlen from dirlist;
		quit;
		%put &amp;amp;=maxlen;

		* Initiate output file;
		data _null_;
			file "&amp;amp;outfile";
			datetime = datetime();
			put "* Error file list generated at " datetime datetime.;
			put "* Error File" @%eval(&amp;amp;maxlen+2) 'Recno' @+2 'Error Line';
		run;

		* loop over files;
		%do i=1 %to &amp;amp;filesfound;

			data _null_; set dirlist (firstobs=&amp;amp;i obs=&amp;amp;i);
				call symput('thisinfile',fullfilename);
			run;

			data _null_;
				 infile "&amp;amp;thisinfile" lrecl=255;
				 file "&amp;amp;outfile" mod;
			 	 input;
				 recno = _N_;
				 if _infile_ =: 'ERROR:' then put "&amp;amp;thisinfile" @%eval(&amp;amp;maxlen+2) recno 5. @+2 _infile_;
			run;
		%end;
	%end;
%end;
%mend;
%read;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 29 Mar 2018 19:19:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/449745#M113242</guid>
      <dc:creator>ErikLund_Jensen</dc:creator>
      <dc:date>2018-03-29T19:19:16Z</dc:date>
    </item>
    <item>
      <title>Re: scan multiple files and write list of file name in which contain error</title>
      <link>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/449758#M113243</link>
      <description>&lt;P&gt;Thank you for the quick reply. In my C:\temp directory, there are several log files and no sub-directories. I’ve change path to C:\temp and run your code to generate dataset dirlist.&amp;nbsp; I got an empty dataset. &amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 29 Mar 2018 19:59:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/449758#M113243</guid>
      <dc:creator>nnl3256</dc:creator>
      <dc:date>2018-03-29T19:59:46Z</dc:date>
    </item>
    <item>
      <title>Re: scan multiple files and write list of file name in which contain error</title>
      <link>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/450259#M113377</link>
      <description>&lt;P&gt;Hi.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Interesting - It Works fine for me.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Try to insert a&lt;U&gt; put rec $char200.;&lt;/U&gt;&amp;nbsp;statement after the Input statement,&amp;nbsp;It lists all input lines in the log, so you can see the lines that goes into the rest of the code. If you don't get the files listed, then something is wrong with the DIR command, otherwise it should be possible to see where the problem occurs. Use similar put- statements to see whether&amp;nbsp;the if-constructs become true and what you get there.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 01 Apr 2018 18:27:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/450259#M113377</guid>
      <dc:creator>ErikLund_Jensen</dc:creator>
      <dc:date>2018-04-01T18:27:05Z</dc:date>
    </item>
    <item>
      <title>Re: scan multiple files and write list of file name in which contain error</title>
      <link>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/450267#M113380</link>
      <description>&lt;P&gt;There are options you can add to your DIR command to make that part easier.&amp;nbsp; To get just the names of files add the /b and /a-d options.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;dir /s/b/a-d&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;There are easier ways to read the filenames. Use the TRUNCOVER option on the INFILE statement.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;infile "dir c:\temp /s/b/a-d" pipe truncover ;
input filename $256. ;	 &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Also if you are looking for actual SAS error messages in the log then you should look for lines that start with 'ERROR' and also contain and ':'.&amp;nbsp; &amp;nbsp;Sometimes SAS will insert information between the 'ERROR' and the colon.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Making sure it starts in column 1 will eliminate many false positives from lines that are just echoing code that might be used by a programmer to generate an error message like&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;if age &amp;lt; 0 then put 'ERROR: Invalid age. ' age=;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;So putting it together you want something like this:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let path=c:\temp;

data logfiles ;
  infile %sysfunc(quote(dir "&amp;amp;path" /b/s/a-d)) pipe truncover ;
  input filen $256. ;
  filename=filen ;
  if index(filename,'.') and lowcase(scan(filename,-1,'.'))='log' ;
  infile saslog filevar=filen end=eof ;
  nerrors=0;
  do lineno=1 by 1 while (not eof);
    input;
    if _infile_=:'ERROR' and index(_infile_,':') then do;
      if not nerrors then put filename= ;
      putlog lineno= _infile_ ;
      nerrors+1;
    end;
  end;
  keep filename nerrors ;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;If you just want the filenames with errors then you can make it even simpler and stop reading the LOG file when you get a hit.&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let path=c:\temp;

data logfiles ;
  infile %sysfunc(quote(dir "&amp;amp;path" /b/s/a-d)) pipe truncover ;
  input filen $256. ;
  filename=filen ;
  if index(filename,'.') and lowcase(scan(filename,-1,'.'))='log' ;
  infile saslog filevar=filen end=eof ;
  anyerrors=0;
  do while (not eof and not anyerrors);
    input;
    if _infile_=:'ERROR' and index(_infile_,':') then anyerrors=1;
  end;
  if anyerrors;
  keep filename ;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Apr 2018 13:43:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/450267#M113380</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2018-04-05T13:43:37Z</dc:date>
    </item>
    <item>
      <title>Re: scan multiple files and write list of file name in which contain error</title>
      <link>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/451492#M113841</link>
      <description>&lt;P&gt;&amp;nbsp;Thank you so much, Tom. it works exactly as I expected.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Apr 2018 13:23:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/scan-multiple-files-and-write-list-of-file-name-in-which-contain/m-p/451492#M113841</guid>
      <dc:creator>nnl3256</dc:creator>
      <dc:date>2018-04-05T13:23:45Z</dc:date>
    </item>
  </channel>
</rss>

