Импорт имени пользователя владельца при импорте файла в SAS

В настоящее время я импортирую несколько сотен файлов в SAS, используя зацикленный оператор infile на основе таблицы, содержащей все интересующие пути и имена файлов. Теперь я хочу импортировать атрибуты каждого файла, чтобы получить имя пользователя, создавшего каждый файл. Я пытался использовать finfo для получения переменной «Владелец», но не уверен, что это правильный вариант для использования. Код, который я использовал, выглядит примерно так:

filename fileref 'file.csv';                                                                                                          
data a(drop=fid);                                                                                                                       
infile fileref truncover obs=1;                                                                                                       
fid=fopen('fileref');     
fnum = foptnum(fid); 
Bytes=finfo(fid,'File Size bytes)');                                                                                                 
crdate=finfo(fid,'Create Time');                                                                                                      
moddate=finfo(fid,'Last Modified');  

owner=foptname(fid,2);
owner2 = finfo(fid,owner); 
Owner1 = finfo(fid,'Owner');
run; 

Любая помощь будет принята с благодарностью.


person Sherazon    schedule 11.05.2017    source источник
comment
Какую ОС вы используете? Поведение finfo зависит от ОС.   -  person user667489    schedule 11.05.2017
comment
Извините, я использую окна   -  person Sherazon    schedule 11.05.2017


Ответы (2)


Ниже приведен пример использования ранее упомянутого подхода dir /q. Должно быть полезно читать несколько файлов в папке, сохраняя при этом атрибуты файла.

%let target_dir = %str(C:\csv_files);
filename DrLst pipe "dir ""&target_dir.\*.csv"" /Q";
%let DELIM   = ' ' ;
data readFiles;
    length infile_path
           filename $255 
           line $1024 
           owner $17 
           temp $16 ;
    infile DrLSt length=reclen;
    input line $varying1024. reclen;
    /*For each csv file found, obtain the file information and read the file contents*/
    if    index(line,"<DIR>") eq 0 and substr(line,1,1) in('0','1') then do;
        createDate = input( scan( line, 1, &DELIM ), mmddyy8. ) ;
        createTime = input( scan( line, 2, &DELIM ), time10. ) ;
        size       = input( scan( line, 4, &DELIM ), best8.) ;
        owner      =        scan( line, 5, &DELIM ) ;

        /*Parsing the filename is tricky*/
        filename = scan( line, 6, &DELIM ) ;
        ndx = index( line, scan( filename, 1 )) ;
        filename = substr( line, ndx ) ;

        /*Now read in the found csv file*/
        infile_path = cat("&target_dir.\",strip(filename));
        infile temp filevar=infile_path dsd dlm=',' end=temp_end;
        do until (temp_end);
            input csvVar1 : $char50.
                  vscVar2 : $char50.;
            output;
        end;
    end;
    drop ndx line temp;
run;
person Hugs    schedule 12.05.2017
comment
Сладкий! Боже скорости. - person Hugs; 17.05.2017

Имя пользователя владельца файла может быть недоступно через функцию finfo для файлов в вашей среде. Вы можете просмотреть имена доступных элементов для файла, выполнив следующее:

data _null_;
fileref = "myfile";
rc = filename(fileref,"C:\temp\class.csv");
put rc=;
fid = fopen(fileref);
put fid=;
nopts = foptnum(fid);
do i = 1 to nopts;
  optname = foptname(fid,i);
  put optname=;
end;
rc = fclose(fid);
run;

Если file owner или что-то подобное не указано для файлов в вашей среде, этот подход не сработает. Вам нужно будет получить имя другим способом, например. путем передачи команды dir /Q для рассматриваемого файла.

Примером использования функций управления файлами может быть:

data _null_;
fileref = "myfile";
/*
The line output by the command below will look something like this:
28/09/2016  13:29               437 user                   class.csv
*/
rc = filename(fileref,"dir /q c:\temp\class.csv | findstr class.csv",'pipe');
fid = fopen(fileref,'s');
rc = fread(fid);
length junk $100 username $32;
/*fget reads 1 word at a time, so throw away the 3 before the username*/
do i = 1 to 3; 
rc = fget(fid, junk);
end;
rc = fget(fid, username);
rc = fclose(fid);
put _all_;
run;

Если вы действительно заинтересованы, также возможно воспроизвести все вышеперечисленное в чистом коде макроса, заключив каждый вызов функции в %sysfunc().

person user667489    schedule 11.05.2017
comment
Как насчет примера метода трубопровода dir /q? ;-) - person Robert Penridge; 11.05.2017
comment
@RobertPenridge Я приведу пример, если спрашивающий заинтересован. Насколько я знаю, возможно, они используют finfo, потому что им приходится жить с option noxcmd, и в этом случае решения может не быть. - person user667489; 11.05.2017
comment
@user667489 user667489 Спасибо за этот фрагмент кода, я пытался его использовать, но думаю, вы правы, информация о владельце недоступна при использовании finfo. Не могли бы вы привести пример метода dir /q, пожалуйста? Я все еще могу использовать команды cmd. - person Sherazon; 12.05.2017