By excecuting the following code i am facing the error marked in red:
%Macro read;
%let fileinfo=codedir;
%DO I = 1 %TO &maxlib;
DATA test3;
Pipe_command = "dir /s /b "||'"'||&&lib&I||'"';
PUT PIPE_COMMAND=;
CALL SYMPUT ('Pipe_command', Pipe_command);
RUN;
%PUT &Pipe_command;
%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command)),pipe);
%END;
%Mend read;
%read;
All lines are working fine except
%sysfunc (FILENAME (fileinfo,%nrbquote (&Pipe_Command)),pipe);
The error is:
SYMBOLGEN: Macro variable PIPE_COMMAND resolves to dir /s /b "C:\sametime"
ERROR: Format name PIPE not found or the width and/or decimal specified for the format used are out
of range.
MPRINT(READ): 20017;
MLOGIC(READ): %DO loop index variable I is now 2; loop will not iterate again.
MLOGIC(READ): Ending execution.
NOTE: Line generated by the macro function "SYSFUNC".
1 20017
-----
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
I need a outfile named as CODEDIR containg the output of line ,%str (&Pipe_Command).
Need your suggestions to resolve the issue.
Thanks in advance..
%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command)),pipe);
I think the there should be just one closing brace after &Pipe_Command.
%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command) ,pipe));
is that NRBQUOTE or STR?
looks like NRBQUOTE has "eaten" one of those close-brackets.
Ani
the mixture of data step and macro environment may be getting in the way here.
The purpose seems to be to invoke filename functions, each establishing a pipe to list files in a folder and the subfolders under that.
One caution :- only one fileref is used, so either more processing is to be performed between the loops or a counter suffix is needed on the fileref that will be assigned.
I would suggest :-
1
use the data step to invoke the filename function - as it is function designed to be invoked in data step.
2
in the data step, loop i=1 to maxlib
3
As appending a suffix to the fileref codedir will limit the list of code libraries to 9, abbreviate that to "code" (the context indicates it is a "dir")
4
insert some code (call execute?) to do something with the fileref
Here is my interpretation of a possible solution:
%Macro codedir( folders /* delimited list of folders */
, delimiter= # /* delimiter between folders */
, out= folder_list /* data set to hold list of folders and RC from filename function */
, files= files_list /* data set to hold list of files found in folders */
) ;
proc delete data= &files ;
run ;
DATA &out (keep= rc fileref folder ) ; ;
retain Pipe_c 'dir /s /b ' ;
length folder $1000 fileref $8 ;
maxlib = countw( "&folders", "&delimiter" ) ;
do i=1 to maxlib ;
folder = scan( "&folders" , i , "&delimiter" ) ;
fileref= 'code' !! put(i,4.-L) ;
rc= FILENAME( fileref
, quote( Pipe_c !! quote( trim( folder ) ) )
, 'pipe' ) ;
output ;
* submit for execution later, code to collect list of files in code folders;
call execute( 'data a ;' ) ;
call execute( ' infile code' !! put( i, 4.-L ) ) ;
call execute( '; input line $char1000. ; run; ' ) ;
call execute( 'proc append base=&files ; run ;' ) ;
end ;
stop ;
RUN;
%Mend codedir ;
option compress=yes ;
%codedir( savian#ArtC.book1)
(tested OK)
"Savian" and "ArtC.book1" are folders under the "current folder" of my SAS session
peterC
Hi Peter,
Thanks for your inputs!
But I have no scope to pass parameters in the code. Actually I just need to produce a output file named as codedir which will contain the result of dir /s /b "C:\Smaetime"
C:\Smaetime: is the local path of my system.
DATA test3
Pipe_command = "'dir /s /b "||'"'||&&lib&I||'"'||"'";
PUT PIPE_COMMAND=;
CALL SYMPUT ('Pipe_command', Pipe_command);
RUN;
%PUT &Pipe_command;
FILENAME codedir pipe &Pipe_Command;
When I use FILENAME codedir pipe &Pipe_Command;
Its not working. This is why I tried the following way:
%Macro read;
%let fileinfo=codedir;
%DO I = 1 %TO &maxlib;
DATA test3;
Pipe_command = "dir /s /b "||'"'||&&lib&I||'"';
PUT PIPE_COMMAND=;
CALL SYMPUT ('Pipe_command', Pipe_command);
RUN;
%PUT &Pipe_command;
%sysfunc (FILENAME (fileinfo,%str (&Pipe_Command)),pipe);
%END;
%Mend read;
%read;
And here I face the error:
SYMBOLGEN: Macro variable PIPE_COMMAND resolves to dir /s /b "C:\sametime"
ERROR: Format name PIPE not found or the width and/or decimal specified for the format used are out
of range.
MPRINT(READ): 20017;
MLOGIC(READ): %DO loop index variable I is now 2; loop will not iterate again.
MLOGIC(READ): Ending execution.
NOTE: Line generated by the macro function "SYSFUNC".
1 20017
-----
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
My concern is not in the maxlib count or anyother count. I just need the output of the dir /s /b "C:\Smaetime" in a file and then i'll use this a file as a input.
Thanks in advance
then it becomes simpler
just the data step to create and run a step to use the fileref creating sas table "work.filelist"
replace C:\temp with your folder
DATA _null_ ;
length fileref $8 ;
retain Pipe_c 'dir /s /b "C:\temp" ' fileref 'codedir' ;
rc= FILENAME( fileref
, quote( Pipe_c )
, 'pipe' ) ;
* submit for execution later, code to collect list of files in code folders;
call execute( 'data filelist( compress=yes );' ) ;
call execute( ' infile codedir lrecl=1000 ;' ) ;
call execute( '; input line $char1000. ; run; ' ) ;
call execute( 'FILENAME CODEDIR ;' ); * to release the fileref ;
stop ;
RUN;
Hi Peter,,
Thanks again for your help and it really good. But when I move to the next step :
DATA Search_Obj_Names (KEEP=Srch_File Program_Nam Path);
EOFC = 0;
INFILE codedir MISSOVER TRUNCOVER END=EOFC ;
RETAIN cnt 0;
INPUT @ 1 Srch_File $256.
;
cnt + 1;
Backward = REVERSE(TRIM(srch_file));
last_slash = INDEX(Backward, '\');
IF last_slash = 0 THEN
last_slash = INDEX(Backward, '/');
IF Last_slash = 0 THEN
DO;
Program = Srch_file;
Path = Srch_file;
END;
ELSE
DO;
Program_Nam = REVERSE(SUBSTR(Backward, 1, Last_slash - 1));
Path = STRIP(REVERSE(SUBSTR(backward, Last_slash)));
END;
S7 = INDEX (Program_Nam, 'sas7bdat');
IF S7 THEN;
ELSE
OUTPUT;
RUN;
It throws an error :
ERROR: No logical assign for filename CODEDIR.
Please look into this and put your inputs plz.
Thanks in advance
I had half anticipated what you wanted, and loaded the physical names - then released CODEDIR
Either you you remove the last call execute() statement
call execute( 'FILENAME CODEDIR ;' ); * to release the fileref ;
or adapt your data step.
CODEDIR returns the bare path and filename.
The following code works onn WIN and UNIX platforms, but not on zOS and probably not on VMS
I would suggest you adapt your process.
Parsing the lines returned by CODEDIR might be easier with the scan() function
filename = scan( line, -1, '/\' ) ; * neither / not \ will appear in filenames you are concerned about;
filetype = scan( filename, -1, '.' ) ;
if filetype = 'sas7bdat' then SAS_ds_name = upcase( scan( filename, 1, '.' )) ;
else
if lowcase(filetype) = 'sas' then prog_name = filename ;
not sure why you identify sas7bdat and then ignore them..
data ds_and_progs ;
set filelist ;
length filename $100 filetype $8 prog_name $40 sas_ds_name $32 filepath $1000;
filename = scan( line, -1, '/\' ) ;
* neither / not \ will appear in filenames you are concerned about;
filetype = scan( filename, -1, '.' ) ;
if filetype = 'sas7bdat' then
SAS_ds_name = upcase( scan( filename, 1, '.' )) ;
else
if lowcase(filetype) = 'sas' then
prog_name = filename ;
else delete ;
filepath = substr( line, 1, length(line) - length( filename) -1 ) ;
run ;
.
pick the results you want
Please try this
FILENAME CODEDIR PIPE "dir /s /d c:\sametime";
DATA DSN;
INFILE CODEDIR TRUNCOVER;
INPUT VAR1 $ 50.;
.....
SAS STATEMENTS
.....
RUN;
you can use this CODEDIR anywhere in your program.
Hope this helps
Thanks
Dhanasekaran R
Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.
Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.
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.