Erstellen von Dateilisten - Erfasssen von Dateiattributen

Hallo zusammen,

kann mir jemand sagen, ob es mit SAS die Möglichkeit gibt eine Liste von Ordner und Dateien zu erstellen, die im Windows-Explorer unter einem besteimmten verzeichnis stehen ?

Aufgabenstellung:
Es soll ein Verzeichnis aller Dateien und Ordner erstellt werden, die unter x:\Ordner abgelegt werden.

Neben dieser Liste sollen nun für die Dateien auch noch bestimte Dateiattribute erfasst werden. Hier sind vor allem von Fotos (*.jpg ) die Aufnahmedaten interessiert. Auch wäre es schön, wenn man das letzte Änderungsdatum der Datei erfassen könnte.

Hat jemand eine Idee?

Gruß E. Berger

... habe die Vorschläge aus diesem Thread mal konsolidiert

Das Ergebnis sind zwei Programme, die auf allen möglichen Plattformen (namentlich: Windows, Unix, MVS) Dateilisten erstellen.

file_lister.sas (Code gibt's hier) ... implementiert den Algorithmus auf Basis von Pipes,

Beispiel unter Windows:

%macro file_lister
(  pfad = %str(C:\Program Files\SAS Institute\SAS\V8\core)
 , file = *.sas
 , outlib = work
 , outtab = file_list
);

file_finder.sas (Code gibt's hier) ... arbeitet unter Windows und (ungetestet!) Unix mit den Funktionen DOPEN, FOPEN, ...; unter MVS wird IDCAMS verwendet.

Beispiel unter Windows:

%file_finder                                                         
(  directoryName = %str(C:\Program Files\SAS Institute\SAS\V8\core)  
 , maxDepth = 2                                                      
 , pattern = *.sas                                                   
 , outFile = files_found                                             
);

Beispiel unter MVS:

%file_finder                                                         
(  directoryName = %str(C:\Program Files\SAS Institute\SAS\V8\core)  
 , maxDepth = 2                                                      
 , pattern = *.sas                                                   
 , outFile = files_found                                             
);

Zu den unterschiedlichen Vorgehensweisen:

Die Pipe-Mimik hat den Vorteil, dass sie recht wenig Code erfordert und schnell zu durchschauen ist. Der große Nachteil ist, dass die Ausgaben der Kommandos "dir" und "ll" variieren je nach Länder- und Sprach-Einstellungen. (... habe bei meinen Tests unter Windows sofort zwei verschiedene Formate angetroffen ... findet sich im Code.)

Die DOPEN...-Funktionen sind grundsätzlich plattform-unabhängig, wobei ich unter Unix allerdings (mangels freier Abende ;-) nicht getestet habe. Aber: Der Code ist halbwegs kryptisch.

Der absolute Exot ist natürlich IDCAMS unter MVS. Hier wird das spektakuläre SAS-Feature genutzt, dass man ein beliebiges MVS-Programm (eben auch IDCAMS) durch vorangestelltes PROC aufrufen kann. Zu beachten ist dabei, dass IDCAMS dei LISTC-Befehl auf SYSIN erwartet; man muß SAS das aufzuführende Programm daher auf einem anderen DD-Namen übergeben ... z.B. so:

//READLOGS EXEC SAS,OPTIONS='SYSIN=SASINPUT',SCL='*'
//SASINPUT DD *

Hope this help! Feedback & Fragen gerne!

Gruß S. Frenzel

Hallo Herr Berger,spontan

Hallo Herr Berger,

spontan fallen mir 2 Möglichkeiten ein:

1) Ausnutzung der SAS Base Funktionen dopen, dnum, doptname, ...
und entsprechend für external files fopen, ...

2) Verwendung der "Pipe" Funktionalität. Dazu ein ein kleiner Auszug aus einem Macro unter Unix, welches sich aber für Win entsprechend anpassen lassen sollte:

%macro chck_ux_file_date(pfad=,file=,outlib=,outtab=);

%if %bquote(&file)=%str(*) %then %do;
filename trf pipe "ll -t &pfad";
%end;
%else %do;
filename trf pipe "cd &pfad; ll -t &file";
%end;

data flist/*(keep=file size kumsize)*/;
attrib ll1 ll2 ll3 ll4 ll5 ll6 ll7 ll8 File length=$128;
attrib size kumsize length=8 format=commax20.
unix_date length=8 format=ddmmyy10.
uhrzeit format=time6.0
tag monat jahr length=8;
infile trf missover ;
input ll1--ll8 file;
if ll1 ne 'insgesamt'; /* erste Zeile ueberlesen falls mehrere Dateien */
if substr(ll1,1,1) ne 'd'; /* keine Verzeichnisse */
.......

Viel Erfolg und
beste Grüsse
Peter Mehnert

Hallo Herr Mehnert,vielen

Hallo Herr Mehnert,

vielen Dank für die Info - ich versuche das mal zu verwirklichen !

Gruß
E. Berger

Hinweis Artikel von Hrn. Frenzel, SASHelp-Tables

Hallo Herr Berger,

eine Antwort auf Ihre Frage habe ich ad hoc leider nicht, aber vielleicht hilft Ihnen der Redscope-Beitrag „OS390-PO-Bibliotheken auf Windows/Unix übertragen (SourceFTP)“ [http://www.redscope.org/node/161] von Herrn Frenzel weiter:

Er beschreibt ein FTPSource-Tool, das eine komplette PO-Bibliothek (d.h. alle Member einer Bibliothek) per Ftp von OS390 auf einen Unix- oder Windows-Rechner überträgt. Hierbei werden vom Großrechner auf den Client Dateien übertragen und können dort in div. Ordnern abgelegt werden. Vielleicht lässt sich dieser Mechanismus auch für Win-Directories anwenden bzw. modifizieren.

Ansonsten werden im Windows-Environment generell SAS-Dateien als Ordner angesprochen (LIBNAME-Statement).

Weiterer Hinweis: Ich weiß, dass in den Help-Tables viele Informationen stehen und denke, dass Sie hierüber vielleicht zum Ziel kommen könnten.

Vielleicht bringt Sie das eine Idee weiter - fahre jedoch gleich zum „SAS-Forum Deutschland“ nach Ulm und werde dort einmal die SAS-Prominenz befragen.

Viele Grüße aus Frankfurt / Main

Marcus Pilz
Projektleiter,
Produktverantwortung 'HV-Auswertungssysteme'

Commerzbank AG

Hallo Herr Pilz,vielen Dank

Hallo Herr Pilz,

vielen Dank für die Anregung! Ich schau mal, ob ich das was zustande bringe.

Gruß

E. Berger

Pragmatischer Lösungsansatz

Hallo Herr Berger,

ich freue mich, dass Sie noch einen weiteren Ansatz zur Lösung Ihrer Anforderung über das Redscope-Forum erhalten haben.

Dennoch, weil ich es zugesagt hatte: aus Ulm ein PRAGMATISCHER Lösungsansatz, der vielleicht nicht schick ist, aber funktionieren sollte (konnte ihn hier nicht testen):

Über das X-Kommando können Sie aus SAS Betriebssystem-Kommandos absetzen. Wenn ich mich richtig an meine DOS-Zeiten erinnere, sollte
das Kommando

DIR /S C: > Datnam.txt

einen Directory Tree in eine Textdatei namens Datnam ausgeben.

Diese Datei können SIe dann klassisch wieder in ein SAS-Programm einlesen

Filename in 'C:\Datnam.txt';

Data Test;
infile in;
input @001 Text $180;

Dann müssten Sie den eingelesenen String unter Umständen noch auseinandernehmen, bspw. mit dem Index-Bafehl.

Viele Grüße von der SFD !

Marcus Pilz
Projektleiter,
Produktverantwortung 'HV-Auswertungssysteme'

Commerzbank AG

Hallo Herr Pilz,bis dato

Hallo Herr Pilz,

bis dato mache ich es genau so, dass ich in der DOS-Umgebung eine Datei erstelle und die dann mit SAS verarbeite .

Wie man aus der SAS-Umgebung DOS Kommandos absetzt ist mit noch unbekannt.

Wie dem auch sei, was mir noch fehlt ist wie man die Informationen "Aufnahmedatum" und "Änderungsdatum" oder auch "Dateigröße" ausliest.

Vielen Dank für Ihr Interesse.

Falls ich eine Lösung finde werde ich sie natürlich hier einstellen.

Gruß
E. berger

Re: Dateiinfos einlesen

Hallo Hr. Berger,

versuchen Sie's doch mal so:

http://support.sas.com/ctx/samples/index.jsp?sid=283&tab=details

Viele Grüße

G. Weist

Dateinfos einlesen

Hallo Herr Weist,

das Ersellen einer Ordner und Dateilsite klappt damit sehr gut. Danke! Das erspart mir doch den umständlichen Weg über DOS .

Wie man aber an bestimmte Dateiinfos (Aufnahmedatum von Fotos) kommt, habe ich nicht rausbekommen.

Gruß

E. Berger

Hallo Herr Berger,

Hallo Herr Berger,

da ich mich heute erst an diesem Forum angemeldet habe kommt meine Antwort etwas später. Aber ich habe da noch was für Sie. Mit dem Freeware Programm jhead.exe können Sie die s.g. EXIF Daten einer Bilddatei auslesen und das sogar rekursiv über mehrere oder alle Unterverzeichsebenen.

Siehe www.sentex.net/~mwandel/jhead/. Mit dem folgenden SAS Datastep können Sie die Ausgabe des Programms für alle *.jpg Dateien unter dem Verzeichnis x:\ordner einlesen:

filename exif pipe "jhead.exe %bquote("x:\ordner\**\*.jpg")";
data work.exif(drop=dummy);
format
path $255.
filename $32.
filedate ddmmyyp10.
filetime time.
;
retain filename path dummy;
infile exif;
input;
if _infile_ =: 'File name' then do;
dummy = reverse(substr(_infile_, 16));
filename = reverse(substr(dummy, 1, index(dummy, '\')-1));
path = left(trim(reverse(substr(dummy, index(dummy, '\')))));
end;
else if _infile_ =: 'File date' then do;
filedate = input(trim(substr(_infile_, 16, 10)), yymmdd10.);
filetime = input(trim(substr(_infile_, 27, 8)), time8.);
output;
end;
run;

Jetzt müssten Sie allerdings in einem weiteren Schritt noch die Dateiattribute (Dateiänderungsdatum etc.) ergänzen.

Eine alternative Lösung wäre die Programmierung eines Perl Scripts, welches die gewünschten EXIF Daten und gleichzeitig die Dateiattribute ausgeben kann. Ich habe ein solches Script mal geschrieben. Wenn Sie Interesse habe würde ich es Ihnen zusenden.

M.f.G.

Thomas Frerichs
Datafocus GmbH
www.datafocus.de

KSFE 2003

Hallo Herr Berger,

hier noch eine (verspätete) Lösung, die auf der KSFE (von Grischa Pfister) unter Tipps und Tricks vorgestellt wurde:

%Let dir = c:\*.txt;
Filename in Pipe "dir &dir";
Data _null_;
Length file $256;
Retain rx;
If ( _n_ = 1 ) Then rx = rxparse(" ( ' '*
' '*
' '
) TO =4 ");
Infile in End = eof;
Input;
If ( rxmatch(rx,_infile_) ) Then Do;
Call rxchange(rx,1,_infile_,file);
Put file=;
End;
If ( eof ) Then Call rxfree(rx);
run;
Filename in Clear;

Dieses Beispiel zeigt den Einsatz vordefinierter Patterns. Ziel ist es, eine Liste aller TXT-Dateien im Verzeichnis „C:\“ zu erstellen. Dafür wird ein Filename vom Typ Pipe auf das entsprechende DOSKommando
gesetzt und das Ergebnis in einem Data-Step eingelesen. Mithilfe eines regulären Ausdruckes werden die Zeilen selektiert, die Dateinamen enthalten (nur diese Zeilen beginnen mit einem Datum, gefolgt von einer Uhrzeit und der Dateigröße), bei der anschließenden Ersetzung werden diese zusätzlichen Informationen entfernt,
so dass nur der Dateiname übrig bleibt.

Sorry, copy and paste Fehler, so sollte es richtig sein

%Let dir = c:\*.txt;
Filename in Pipe "dir &dir";
Data _null_;
Length file $256;
Retain rx;
If ( _n_ = 1 ) Then rx = rxparse(" ( ' '*
' '*
' '
) TO =4 ");
Infile in End = eof;
Input;
If ( rxmatch(rx,_infile_) ) Then Do;
Call rxchange(rx,1,_infile_,file);
Put file=;
End;
If ( eof ) Then Call rxfree(rx);
run;
Filename in Clear;

hallo uefa1997,für mich

hallo uefa1997,
für mich sind die code-sequencen identisch. Vielleicht noch ein
cut and paste problem ?
Gruß
Friedrich von der Emde