Hallo MFAB,
es gibt die Möglichkeit, im Data Step auf den Wechsel der eingelesenen Datei zu reagieren, die automatische Variable EOV wird ab der zweiten gelesenen Datei bei der ersten gelesenen Zeile auf 1 gesetzt (muss aber von Hand wieder zurückgesetzt werden). Damit kannst Du kontrollieren, ob eine neue Datei gelesen wurde und dann einfach soviele Zeilen wie nötig "überlesen". Hier zunächst ein Beispiel mit Deinen Ausgangsdaten:
%Let root = f:/temp; data a1; var1 = 26.3; var2 = "abc"; output; var1 = 26.3; var2 = "abc"; output; run; data a2; diese_zeile = 578.3; macht_probleme = "def"; output; diese_zeile = 578.3; macht_probleme = "def"; output; run; proc export data=a1 dbms=csv outfile="&root/a1.csv" replace; delimiter=';'; run; proc export data=a2 dbms=csv outfile="&root/a2.csv" replace; delimiter=';'; run; data c; length readfile datei $150.; infile "&root/a*.csv" firstobs = 2 dlm=';' eov = newFile filename = readfile ; input @; datei = readfile; put newFile= datei=; If ( newFile ) Then Do; newFile=0 ; End; Else Do; input a : best. b : $char3. ; Output; End; run;
Bei Einlesen der ersten Zeile der zweiten Datei wird NEWFILE auf 1 gesetzt, was dazu führt, dass kein INPUT ausgeführt wird, sondern lediglich der Wert von NEWFILE auf 0 zurückgesetzt wird. Beim Lesen der zweiten Zeile der zweiten Datei wird dann wieder INPUT ausgeführt.
Wenn die Anzahl der zu ignorierenden Zeilen immer gleich ist, kannst Du einfach entsprechend INPUT-Statements ergänzen, wie in diesem Beispiel:
%Let root = f:/temp;
data a1;
output;
output;
var1 = 26.3;
var2 = "abc";
output;
var1 = 26.3;
var2 = "abc";
output;
run;
data a2;
output;
output;
diese_zeile = 578.3;
macht_probleme = "def";
output;
diese_zeile = 578.3;
macht_probleme = "def";
output;
run;
proc export data=a1 dbms=csv outfile="&root/a1.csv" replace;
delimiter=';';
run;
proc export data=a2 dbms=csv outfile="&root/a2.csv" replace;
delimiter=';';
run;
data c;
length readfile datei $150.;
infile "&root/a*.csv"
firstobs = 2
dlm=';'
eov = newFile
filename = readfile
;
input @;
datei = readfile;
put newFile= datei=;
If ( newFile ) Then Do;
newFile=0 ;
Input;
Input;
End;
Else Do;
input
a : best.
b : $char3.
;
Output;
End;
run;
Ich habe einfach zwei Leerzeilen in den Text-Dateien ergänzt, entsprechend wird bei Wechsel der Einlesedatei die erste Zeile ignoriert sowie zwei Zeilen mit INPUT gelesen, ohne Variablen einzulesen.
(habe gerade gesehen das freelanceReinhard eine analoge Antwort schon geschrieben hat...)
Was das Einlesen und Erkennen von Sätzen angeht, verwende ich oft den Ansatz erst die gesammte Zeile zu lesen und dann zu interpretieren, was drinnen steht. Ein INPUT Statement ohne Bezeichner sorgt nämlich dafür, dass die gesamte Zeile in einer internen Variable _INFILE_ landet, und die kann dann untersucht werden. Beispiel:
Data Work.Test;
Length var1 $16 var2 8 var3 $16;
Input;
If ( countw(_infile_,";") = 3 ) Then Do;
var1 = scan(_infile_,1,";");
var2 = input(scan(_infile_,2,";"),??best.);
var3 = scan(_infile_,3,";");
Output;
End;
Cards4;
Hier steht etwas
nach zwei leeren Zeilen steht wieder etwas.
Hier kommt noch ein weiterer String; sogar mit ; getrennt;
Artikel1;2038;VariableXY
Artikel2;2453;VariableXY
Artikel1;2342;VariableXY
;;;;
Run;
Mit Input wird _INFILE_ erzeugt, wenn drei durch Semikolon getrennte Elemente vorhanden sind, wird der String genauer angeschaut und mit scan() werden die Elemente ausgelesen, für VAR2 wird dann noch die Konvertierung CHAR->NUM vorgenommen.
Hoffe, die Antwort hilft weiter,
Viele Grüße,
Grischa
... View more