matbuss
Goto Top

Variablenauflösung innerhalb verschachtelter FOR-Schleife

Hallo allerseits,

ich hoffe Ihr könnt mir bei meiner folgenden Frage helfen. Ich habe schon hier im Forum gesucht, bin allerdings leider noch nicht fündig geworden. Ich finde einfach den Fehler nicht.

Hintergund ist folgender:
Alte PST-Dateien werden automatisch auf einen Server zur Ablage verschoben. Der Dateiname der PST-Dateien entspricht dabei dem Postfachnamen des Benutzers. Zu diesen PST-Dateien sollen jetzt jedoch noch weitere Informationen bereit gestellt werden. Diese Informationen sollen, aus einem mit "#" getrenntem CSV extrahiert werden, dass täglich generiert wird. Diese zusätzlichen Informationen sollen dann als separate Attributdatei mit gleichem Präfix zur PST-Datei und Suffix "txt" abgelegt werden.

Die Ermittlung der PST Dateien ansich sowie die Ermittlung der Attribute ansich funktionieren auch. Problematisch wird dies allerdings jedoch in der Kombination, dann erhalte ich immer die Fehlermeldung "File not found". Ich vermute, dass irgendwie die Variable "!pstName!" in der inneren For-Schleife nicht korrekt aufgelöst wird, allerdings komme ich dem Problem auch nach Stunden nicht auf die Spur.

Die alleinstehende For-Schleife dient zur Ermittlung des Dateinamens, des aktuellsten Reports. Der Dateiname enthält dabei am Ende das Tagesdatum (funktoniert soweit).

Bei den beiden verschachtelten For-Schleifen soll die äußere dazu Dienen, alle bereits im Verzeichnis befindlichen PST-Dateien zu durchlaufen (Skript wird 1x täglich gestartet). Dabei wird das *.pst in *._pst umbenannt, um nicht erneut aufgegriffen zu werden (funktioniert soweit auch). Dann soll für jedes gefundene PST innerhalb der inneren For-Schleife, die Reportdatei durchlaufefen werden, um die entsprechenden Attribute zu übermitteln. Gebe ich den Reportnamen fix ein, funktioniert dies auch, allerdings nicht unter Verwendung von !pstName!.

Wo habe ich hier etwas übersehen?

Vielen Dank im Voraus.

Gruß,
matbuss


@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

REM ------------- GET REPORT FILE - START -----------------
SET filepath=C:\d3\Import\hrt\PST-Transfer
SET filemask=*.csv
SET searchFilter=.csv

FOR /F "tokens=4" %%a IN ('dir "%filepath%\%filemask%" ^| Find /i "%searchFilter%"') DO (  
   SET reportFile=%filepath%\%%a
)
REM ------------- GET REPORT FILE - END -------------------

REM ----------- GET PST ATTRIBUTES - START ----------------
SET filepath=C:\d3\Import\hrt\PST-Transfer
SET filemask=*.pst
SET searchFilter=.pst

FOR /F "tokens=4" %%a IN ('dir "%filepath%\%filemask%" ^| Find /i "%searchFilter%"') DO (  
   SET pstName=%%a
   SET pstName=!pstName:.pst=!
   REN "%filepath%\!pstName!.pst" "!pstName!._pst"  
   ECHO !pstName!
   
   FOR /F "tokens=1-10 delims=#" %%b IN ('findstr /b /i /c:"!pstname!" "%reportFile%"') DO (   
      SET csvPstName=%%b
      SET csvSurname=%%c
      SET csvGivenName=%%d
      SET csvCostUnit=%%e
      SET csvStreet=%%f
      SET csvPostalCode=%%g
      SET csvCity=%%h
      SET csvCompany=%%i
      SET csvDepartment=%%j
      SET csvCountry=%%k

      REM ECHO Name: !csvPstName!
      REM ECHO Surname: !csvSurname!
      REM ECHO Given Name: !csvGivenName!
      REM ECHO Cost Unit: !csvCostUnit!
      REM ECHO Street: !csvStreet!
      REM ECHO Postal Code: !csvPostalCode!
      REM ECHO City: !csvCity!
      REM ECHO Company: !csvCompany!
      REM ECHO Department: !csvDepartment!
      REM ECHO Country: !csvCountry!
   )
)
REM ------------ GET PST ATTRIBUTES - END -----------------
ENDLOCAL

Content-Key: 141278

Url: https://administrator.de/contentid/141278

Printed on: April 23, 2024 at 11:04 o'clock

Member: bastla
bastla Apr 22, 2010 at 15:41:32 (UTC)
Goto Top
Hallo matbuss und willkommen im Forum!

Eigentlich würde ich das eher so versuchen:
@ECHO OFF & SETLOCAL

REM ------------- GET REPORT FILE - START -----------------
SET "filepath=C:\d3\Import\hrt\PST-Transfer"  
SET "filemask=*.csv"  
SET "searchFilter=.csv"  

FOR /F "tokens=4" %%a IN ('dir "%filepath%\%filemask%" ^| Find /i "%searchFilter%"') DO (  
   SET "reportFile=%filepath%\%%a"  
)
REM ------------- GET REPORT FILE - END -------------------

REM ----------- GET PST ATTRIBUTES - START ----------------
SET "filepath=C:\d3\Import\hrt\PST-Transfer"  
SET "filemask=*.pst"  
SET "searchFilter=.pst"  

PUSHD "%filepath%"  
FOR /F "tokens=4" %%a IN ('dir "%filemask%" ^| Find /i "%searchFilter%"') DO (  
   REN "%%a" "%%~na._pst"  
   
   FOR /F "tokens=1-10 delims=#" %%b IN ('findstr /b /i /c:"%%~na" "%reportFile%"') DO (   
      SET csvPstName=%%b
      SET csvSurname=%%c
      SET csvGivenName=%%d
      SET csvCostUnit=%%e
      SET csvStreet=%%f
      SET csvPostalCode=%%g
      SET csvCity=%%h
      SET csvCompany=%%i
      SET csvDepartment=%%j
      SET csvCountry=%%k
   )
)
REM ------------ GET PST ATTRIBUTES - END -----------------
POPD
Die Verwendung des "searchFilters" ergibt in der derzeitigen Form keinen Sinn (eine Zeile
FOR %%a IN ("%filepath%\%filemask%") DO SET "reportFile=%%a"
oder
FOR /F "delims=" %%a IN ('DIR /b "%filemask%"') DO (
sollte schon genügen) ...

... und solange ich nicht weiß, was Du mit den Attributen noch alles anstellen willst, würde ich auch die Variablen dafür einsparen und einfach "%%b" bis "%%k" verwenden.


Grüße
bastla
Member: Biber
Biber Apr 22, 2010 at 15:58:33 (UTC)
Goto Top
Moin matbuss,

willkommen im Forum.

Ich vermute den Fehler in den Zeilen 19-23, die sogar für mich etwas verworren aussehen... und ich habe einiges Wirres zusammengeschrotet.

Also:
....
REM FOR /F "tokens=4" %%a IN ('dir "%filepath%\%filemask%" ^| Find /i "%searchFilter%"') DO (   
REM    SET pstName=%%a 
REM    SET pstName=!pstName:.pst=! 
REM   REN "%filepath%\!pstName!.pst" "!pstName!._pst"   
REM   ECHO !pstName! 
:: -----------wenn überhaupt, dann vielleicht:
FOR /F "tokens=4" %%a IN ('dir "%filepath%\%filemask%" ^| Find /i "%searchFilter%"') DO (   

   REN "%filepath%\!pstName!.pst" "%%~na._pst"   
   ECHO Name ohne Endung %%~na 
   ....

Aber:
Die Datei, die (manchmal) nicht gefunden wird
--> liegt daran, dass du eine Dateiliste durchläufst (FOR-Anweisung in Zeile 19), die du aber innerhalb der For-Anweisung änderst.

Ist vergleichbar einer Schleife, die du von einem Zähler x=1 bis x=100 laufen lässt und im Anweisungsteil dann mal sagst: x = 21

Das Ergebnis ist nicht so genau prognostizierbar.

Du brauchst die Umbenamserei ja nicht wissenschaftlich aufarbeiten, aber sinnvoll wären nur zwei Strategien IMHO:
  • entweder eine SORTIERTE Liste erzeugen mit einem DIR-Befehl o.ä. - meinetwegen nach Datum oder nach Größe. Dann kannst du die Elemente (Dateien) DIESER Liste nach Herzenslust mit anderen Datei-NAMEN oder ENDUNGEN ausgestalten.
  • oder du schreibt die komplette Liste der abzuarbeitenden Dateien in eine Temp-Datei... dann kannst du eine Zeile nach der anderen lesen und die Dateien umbenamsen.

Grüße
Biber

[Edit] ...okay, okay, bastla... der Kaffee hat mir nichts genützt.... ich hol mir mal was Stärkeres... face-wink [/Edit]
Member: bastla
bastla Apr 22, 2010 at 17:02:51 (UTC)
Goto Top
@Biber
entweder eine SORTIERTE Liste erzeugen mit einem DIR-Befehl o.ä. - meinetwegen nach Datum oder nach Größe.
Sollte nicht bereits ein simples "dir /b" genügen, um bereits vorweg eine komplette (und innerhalb der Schleife nicht mehr upgedatete) Dateiliste zu erhalten?

Grüße
bastla

P.S.: Du hättest Dich vielleicht doch für die "lila" Pause entscheiden sollen ... face-smile
Member: matbuss
matbuss Apr 22, 2010 at 17:43:31 (UTC)
Goto Top
Hallo,

danke für die super schnelle Rückmeldung. Ich werde das direkt morgen früh ausprobieren face-smile

Gruß,
matbuss
Member: Biber
Biber Apr 22, 2010 at 20:13:28 (UTC)
Goto Top
[OT] @bastla
Zitat von @bastla:
@Biber
> entweder eine SORTIERTE Liste erzeugen mit einem DIR-Befehl o.ä. - meinetwegen nach Datum oder nach Größe.
Sollte nicht bereits ein simples "dir /b" genügen, um bereits vorweg eine komplette (und innerhalb der Schleife
nicht mehr upgedatete) Dateiliste zu erhalten?

Kann ich beantworten, ob die Liste "nicht mehr upgedated" wird face-wink
(=22:06:08  D:\temp\dideli=)
>copy ..\test*.txt
..\test mit space.txt
..\test.txt
..\test37.txt
..\test777.txt
..\test97.txt
..\test98.txt
..\test99.txt
..\testfiel.txt
..\testout.txt
..\testrar.txt
..\testset.txt
..\testutf.txt
       12 Datei(en) kopiert.

(=22:08:40  D:\temp\dideli=)
>for /f "delims=" %i in ('dir /b *.txt') do @echo if exist *.txt @del *.txt /q && @echo %i done
if exist *.txt @del *.txt /q
test mit space.txt done
if exist *.txt @del *.txt /q
test.txt done
if exist *.txt @del *.txt /q
test37.txt done
if exist *.txt @del *.txt /q
test777.txt done
if exist *.txt @del *.txt /q
test97.txt done
if exist *.txt @del *.txt /q
test98.txt done
if exist *.txt @del *.txt /q
test99.txt done
if exist *.txt @del *.txt /q
testfiel.txt done
if exist *.txt @del *.txt /q
testout.txt done
if exist *.txt @del *.txt /q
testrar.txt done
if exist *.txt @del *.txt /q
testset.txt done
if exist *.txt @del *.txt /q
testutf.txt done

(=22:09:04  D:\temp\dideli=)
>for /f "delims=" %i in ('dir /b *.txt') do @if exist *.txt @del *.txt /q && @echo %i done
test mit space.txt done

(=22:09:50  D:\temp\dideli=)
>
--> der "scharf gemachte" Durchlauf unten ohne "echo" läuft EINmal.

Grüße
Biber

[/OT]
Member: bastla
bastla Apr 22, 2010 at 20:36:55 (UTC)
Goto Top
[OT2]
@Biber
Leider auch mit Sortierung:
D:\Texte>for /f "delims=" %i in ('dir /b /od *.txt') do @echo if exist *.txt @del *.txt /q && @echo %i done
if exist *.txt @del *.txt /q
Binary-1.txt done
if exist *.txt @del *.txt /q
Binary-2.txt done
if exist *.txt @del *.txt /q
Binary-3.txt done
if exist *.txt @del *.txt /q
Binary-4.txt done
if exist *.txt @del *.txt /q
Bin.txt done
if exist *.txt @del *.txt /q
Beispiel_2.txt done
if exist *.txt @del *.txt /q
Beispiel_3.txt done
if exist *.txt @del *.txt /q
Beispiel.txt done
if exist *.txt @del *.txt /q
Beispiel_4.txt done

D:\Texte>for /f "delims=" %i in ('dir /b /od *.txt') do @if exist *.txt @del *.txt /q && @echo %i done
Binary-1.txt done
Aber:
D:\Texte>dir /b *.txt
Binary-1.txt
Binary-2.txt
Binary-3.txt
Binary-4.txt
Bin.txt
Beispiel_2.txt
Beispiel_3.txt
Beispiel.txt
Beispiel_4.txt

D:\Texte>for /f "delims=" %i in ('dir /b *.txt') do copy %i "%~ni_neu%~xi">nul && @echo %i done

D:\Texte>copy Binary-1.txt "Binary-1_neu.txt"  1>nul  &&
Binary-1.txt done

D:\Texte>copy Binary-2.txt "Binary-2_neu.txt"  1>nul  &&
Binary-2.txt done

D:\Texte>copy Binary-3.txt "Binary-3_neu.txt"  1>nul  &&
Binary-3.txt done

D:\Texte>copy Binary-4.txt "Binary-4_neu.txt"  1>nul  &&
Binary-4.txt done

D:\Texte>copy Bin.txt "Bin_neu.txt"  1>nul  &&
Bin.txt done

D:\Texte>copy Beispiel_2.txt "Beispiel_2_neu.txt"  1>nul  &&
Beispiel_2.txt done

D:\Texte>copy Beispiel_3.txt "Beispiel_3_neu.txt"  1>nul  &&
Beispiel_3.txt done

D:\Texte>copy Beispiel.txt "Beispiel_neu.txt"  1>nul  &&
Beispiel.txt done

D:\Texte>copy Beispiel_4.txt "Beispiel_4_neu.txt"  1>nul  &&
Beispiel_4.txt done

D:\Texte>dir /b *.txt
Binary-1_neu.txt
Binary-2_neu.txt
Binary-3_neu.txt
Binary-4_neu.txt
Bin_neu.txt
Beispiel_2_neu.txt
Beispiel_3_neu.txt
Beispiel_neu.txt
Beispiel_4_neu.txt
Binary-1.txt
Binary-2.txt
Binary-3.txt
Binary-4.txt
Bin.txt
Beispiel_2.txt
Beispiel_3.txt
Beispiel.txt
Beispiel_4.txt
Grüße
bastla

[/OT2]
Member: matbuss
matbuss Apr 23, 2010 at 09:09:58 (UTC)
Goto Top
Hallo,

besten Dank für die Hilfe. Habe eure Anmerkungen da mit eingearbeitet und auch die Variablen weg geschmissen. Funktioniert jetzt einwandfrei face-smile.

Gruß,
matbuss