mario.steinberg
Goto Top

Verzeichniswechsel aus For-Schleife heraus

Hallo,

folgendes ist der Plan!

Ich möchte in einer "komplexen" Verzeichnisstruktur alle Dateien mit der Bezeichnung "CMakeLists.txt" finden und auf den jeweiligen Pfaden relative Pfade bilden.
Mit Hilfe dieser relativen Pfanden sollen dann neue Verzeichnisse erstellt werden.

Z.B.
Aus C:\MyWorkspace\Verzeichnis1\SubVerzeichnis23\CMakeLists.txt extrahiere ich (evtl. weiß jemand wie ich das Problem schöner lösen kann)
Verzeichnis1\SubVerzeichnis23 (<<== RelPath aus Code). Daraus erzeuge ich das neue Verzeichnis D:\WorkspaceNeu\Verzeichnis1\SubVerzeichnis23 (D:\WorkspaceNeu\!RelPath!).

Bis dahin laüft alles recht gut.

Nun soll aus der For-Schleife heraus in das neu erzeugte Verzeichnis gesprungen werden, und von dort irgendwas gemacht werden.
In meinem Beispiel erzeuge ich mittels CMake VS Projektdateien. Diese sollen in dem neu angelegten Verzeichnis landen.
Das CMakeLists.txt dazu liegt im ursprünglichen Pfad.

%CMAKE_CMD% und %CMAKE_GENERATOR% sind gesetzt!

@echo off & setlocal enabledelayedexpansion

set WORKSPACE=C:\MyWorkspace
set TARGET_DIR=D:\WorkspaceNeu

pushd .
cd /D %WORKSPACE%

for /f "delims=" %%i in ('dir /s /b "CMakeLists.txt"') do (   
    set "RelPath=%%i"   
    set "RelPath=!RelPath:%WORKSPACE%\=!  
    set "RelPath=!RelPath:\CMakeLists.txt=!  
    if not exist %TARGET_DIR%\!RelPath! mkdir %TARGET_DIR%\!RelPath!
    pushd .
    cd /D %TARGET_DIR%\!RelPath!
    %CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt
    popd
)
popd
pause
:END
echo DONE

Leider kann ich offensichtlich mittels cd /D %TARGET_DIR%\!RelPath! aus der For-Schleife heraus nicht in ein anderes Verzeichnis wechseln.
Gibt es dafür eine Lösung?

Wo gibt es in meinem Code noch Verbesserungsmöglichkeiten?

Vielen Dank schon mal für eure Hilfe.

Gruß,
Mario

Content-ID: 138359

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

Ausgedruckt am: 19.11.2024 um 20:11 Uhr

bastla
bastla 16.03.2010 um 13:26:44 Uhr
Goto Top
Hallo Mario.Steinberg!

Wenn der Wechsel des Verzeichnisses aus anderen Gründen wichtig sein sollte, dann zumindest mit der dafür vorgesehenen Verwendung von "pushd":
pushd "%TARGET_DIR%\!RelPath!"  
%CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt
popd
Wo gibt es in meinem Code noch Verbesserungsmöglichkeiten?
Es sollte eigentlich genügen, den Pfad der gefundenen Datei als Ausgangspunkt zu nehmen (und damit die Zeile 12 einzusparen):
set "RelPath=%%~dpi"  
set "RelPath=!RelPath:%WORKSPACE%\=!  
Dass sich am Ende von !RelPath! dadurch noch ein "\" befindet, kannst Du zur Not auch ignorieren ...

Grüße
bastla
Mario.Steinberg
Mario.Steinberg 16.03.2010 um 14:22:03 Uhr
Goto Top
Hallo bastla,

danke für die Antwort. Tipp 2 ist klasse.
Für den Tipp 1 muss ich evtl. noch etwas genauer werden.

Ich befinde mich in %WORKSPACE% (C:\MyWorkspace) und starte die For-Schleife.
In einem der vielen Unterverzeichnisse von %WORKSPACE% finde ich eine CMakeLists.txt z.B. %WORKSPACE%\Verzeichnis1\SubVerzeichnis23\CMakeLists.txt
Dann soll das Verzeichnis %TARGET_DIR%\Verzeichnis1\SubVerzeichnis23 erzeugt und dort hinein gewechselt werden.

Wir befinden uns nun in %TARGET_DIR%\Verzeichnis1\SubVerzeichnis23
CMake nimmt sich die Datei CMakeList.txt aus %WORKSPACE%\Verzeichnis1\SubVerzeichnis23\CMakeLists.txt und erzeugt die Projektdateien in dem aktuellen Verzeichnis, also %TARGET_DIR%\Verzeichnis1\SubVerzeichnis23.

Danach soll die For-Schleife weiter laufen und ggf. in einem anderen Unterverzeichnis eine neue CMakeLists.txt finden u.s.w.

Leider funktioniert der Verzeichniswechsel von %WORKSPACE%\Verzeichnis1\SubVerzeichnis23\ nach %TARGET_DIR%\Verzeichnis1\SubVerzeichnis23 nicht.

pushd . 
cd /D %TARGET_DIR%\!RelPath! 
%CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt 
popd 

Was passiert mit der For-Schleife wenn ich in ein anderes Verzeichnis wechsel? Ich nehme an ich muss nach getaner Arbeit wieder irgendwie zurück!?
bastla
bastla 16.03.2010 um 15:03:57 Uhr
Goto Top
Hallo Mario.Steinberg!

Meine ersten 3 Zeilen waren als Ersatz für Deine nochmals dargestellten 4 Zeilen gedacht (die zwar auch funktionieren sollten, aber Du hattest ja nach Verbesserungsmöglichkeiten gefragt face-wink) ...

... ansonsten dürfte das Problem aber darin liegen, dass mit "%CMAKE_CMD%" vermutlich ein anderer Batch gestartet wird; wenn dem so ist, dann bitte ein "call" davor, also:
call %CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt
da anderenfalls kein Rücksprung in die Schleife erfolgt.

Grüße
bastla
Mario.Steinberg
Mario.Steinberg 16.03.2010 um 15:31:23 Uhr
Goto Top
Ah verstehe!!!

pushd "%TARGET_DIR%\!RelPath!" sichert den Pafd des aktuellen Verzeichnisses und wechselt dann nach "%TARGET_DIR%\!RelPath!"!?

Nett - nur leider funktioniert das irgendwie nicht.
Wenn ich nach dem Aufruf, egal wie dieser nun aussah, echo %cd% sage, zeigt er trotzdem %WORKSPACE% als Pfad an.
bastla
bastla 16.03.2010 um 16:16:16 Uhr
Goto Top
Hallo Mario.Steinberg!
Nett - nur leider funktioniert das irgendwie nicht.
Lässt sich das "irgendwie" noch an mehr festmachen als an "Wenn ich ... echo %cd% sage, zeigt er trotzdem %WORKSPACE% als Pfad an."?
Wenn nein, dann sag doch mal versuchsweise
echo !cd!
oder auch nur
cd
Grüße
bastla
Mario.Steinberg
Mario.Steinberg 17.03.2010 um 08:17:38 Uhr
Goto Top
Hallo bastla,

echo %cd% scheint nicht zu taugen. Ich hatte es auf der Suche nach "pwd für Windows" gefunden.
echo !cd! und cd sind besser face-smile

Das Problem ist gelöst. Er ist tatsächlich in das Verzeichnis gewechselt nur mein Aufruf

%CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt 

war mist. Warum acuh immer funktioniert es so

%CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!

besser. Nun gabe ich da noch eine kleine Frage. Wie kann ich verhindern, dass die For-Schleife, wenn sie eine CMakeList.txt in einem Verzeichnis gefunden hat, in den Unterverzeichnissen dieses Verzeichnises weitersucht.

z.B.
..\ver1\sub1\CMakeLists.txt <-das soll er finden
..\ver1\sub1\sub2\CMakeLists.txt <-das nicht
..\ver1\sub2\CMakeLists.txt <-das aber wieder

Danke für deine Hilfe und Gruß,
Mario
bastla
bastla 20.03.2010 um 11:41:25 Uhr
Goto Top
Hallo Mario.Steinberg!

Mit Verspätung (und noch dazu nur oberflächlich getestet) face-sad:
@echo off & setlocal enabledelayedexpansion

set WORKSPACE=C:\MyWorkspace
set TARGET_DIR=D:\WorkspaceNeu
set "Done=%temp%\Done.txt"  

pushd %WORKSPACE%
copy nul "%Done%">nul  
for /f "delims=" %%i in ('dir /s /b "CMakeLists.txt"') do (   
    echo %%~fi|findstr /L /G:"%Done%">nul 2>nul || (  
        set "RelPath=%%~dpi"  
        >>"%Done%" echo !RelPath!  
        set "RelPath=!RelPath:%WORKSPACE%\=!  
        if not exist %TARGET_DIR%\!RelPath! mkdir %TARGET_DIR%\!RelPath!
        pushd %TARGET_DIR%\!RelPath!
        %CMAKE_CMD% -G %CMAKE_GENERATOR% %WORKSPACE%\!RelPath!
        popd
    )
)
popd

:END
echo DONE
echo\
echo Verarbeitet wurden:
type "%Done%"  
pause
Grüße
bastla
Biber
Biber 20.03.2010 um 12:12:08 Uhr
Goto Top
Moin bastla, moin Mario.Steinberg,

wenn du jetzt aber das Setzen der Variable %RelPath% richtigerweise auf den Pfad beschränkst (ohne Dateiname/Extension),
dann muss in Zeile 16
%CMAKE_CMD% -G %CMAKE_GENERATOR% %WORKSPACE%\!RelPath!
... wieder der (feste, immer gleiche) Name "CMakeLists.txt" an das Ende gestellt werden.

IMHO gehen Skripte immer in die Grütze, wenn das Verhältnis verwendeter Variablen zu verwendeten Kommentarzeilen (der sogenannte Munter-Runter-Klimper-Koeffizient MRKK) einen Wert >= 10 annimmt oder gar einen #Div/0!#-Error wirft.

Siehe Marios "warum-auch-immer"-Fehlersuche einen Kommentar zuvor.

Grüße
Biber
bastla
bastla 20.03.2010 um 13:01:44 Uhr
Goto Top
Hallo Mario.Steinberg und Biber!

Wenn Bibers Vermutung hinsichtlich der Zeile 16 zutrifft (woran ich keineswegs zweifle - ich hatte mich nur an die Erfolgsmeldung im letzten Kommentar von Mario.Steinberg gehalten), sollte sich diese Zeile eigentlich auf
%CMAKE_CMD% -G %CMAKE_GENERATOR% "%%i"
reduzieren lassen ...

Grüße
bastla
Biber
Biber 20.03.2010 um 13:13:44 Uhr
Goto Top
[OT]
@bastla

Zitat von @bastla:
ich hatte mich nur an die Erfolgsmeldung im letzten Kommentar von Mario.Steinberg gehalten
Ich will mal so sagen: tagespolitische Meldungen wie "Die Gespräche fanden in konstruktiver Atmosphäre statt" oder "Die Folgen der Krise müssen überwunden werden" wie auch Aussagen aus dem Entwickler-Bereich "Es funktioniert - warum auch immer." würde ich nicht automatisch als "Erfolgsmeldungen" bezeichnen. face-wink

Grüße
bastla
Grüße zurück
Biber
[/OT]
bastla
bastla 20.03.2010 um 13:46:05 Uhr
Goto Top
@Biber
[OT]
Es funktioniert ..." ist auf jeden Fall ein Erfolg - früher stand da in solchen Fällen ja eher "Es funtzt ..." face-wink
[/OT]

Grüße
bastla
Mario.Steinberg
Mario.Steinberg 22.03.2010 um 14:37:16 Uhr
Goto Top
Hallo bastla, hallo Biber,

bezüglich

wenn du jetzt aber das Setzen der Variable %RelPath% richtigerweise auf den Pfad beschränkst (ohne Dateiname/Extension),
dann muss in Zeile 16
%CMAKE_CMD% -G %CMAKE_GENERATOR% %WORKSPACE%\!RelPath!
... wieder der (feste, immer gleiche) Name "CMakeLists.txt" an das Ende gestellt werden.

IMHO gehen Skripte immer in die Grütze, wenn das Verhältnis verwendeter Variablen zu verwendeten Kommentarzeilen (der sogenannte Munter-Runter-Klimper-Koeffizient > MRKK) einen Wert >= 10 annimmt oder gar einen #Div/0!#-Error wirft.

weiß ich nicht genau was gemeint ist.
Fakt ist, das der CMake Aufruf ohne die Dateibezeichnung "CMakeLists.txt" erfolgen muss. Offensichtlich weiß CMake selbst welche Datei er zur Abarbeitung benötigt wird.

Bezüglich

Mit Verspätung (und noch dazu nur oberflächlich getestet) von bastla

Habe folgenden Code an einem Beispiel versucht


...
pushd %WORKSPACE%
copy nul "%Done%">nul
for /f "delims=" %%i in ('dir /s /b "CMakeLists.txt"') do (

set "RelPath=%%~dpi"
>>"%Done%" echo !RelPath!
set "RelPath=!RelPath:%WORKSPACE%=!
)
)
popd

:END
echo DONE
echo\
echo Verarbeitet wurden:
type "%Done%"


und dieses Ergebnis erhalten
...
C:\MyWorkspace\Src\MsgMgr\
C:\MyWorkspace\Src\MsgMgr\MsgMgrServer\
C:\MyWorkspace\Src\MsgMgr\MsgMgrClient\
...

Hatte aber eigentlich soetwas gewollt.
...
C:\MyWorkspace\Src\MsgMgr\
...

Da in C:\MyWorkspace\Src\MsgMgr\ bereits ein CMakeLists.txt liegt, soll er in die die darunterliegenden Verzeichnisse nicht mehr rein gehen.

Ich versuche mal zu verstehen, was genau
macht. Sollte zuvor jemand eine Lösung zu dem Problem haben, würde ich mich natürlich auch sehr freuen.

Schon mal danke für eure kompetente Hilfe und Gruß,
Mario
bastla
bastla 22.03.2010, aktualisiert am 18.05.2014 um 18:23:50 Uhr
Goto Top
Hallo Mario.Steinberg!
Ich versuche mal zu verstehen, was genau
macht.
Bei mir macht's eigentlich, was es soll:
C:\>tree /f C:\MyWorkspace
Auflistung der Ordnerpfade für Volume Tests
Volumenummer: 1234-5678
C:\MYWORKSPACE
└───Src
    ├───MsgMgr
    │   │   CMakeLists.txt
    │   │
    │   ├───MsgMgrServer
    │   │       CMakeLists.txt
    │   │
    │   └───MsgMgrClient
    │           CMakeLists.txt
    │
    └───MsgMgr2
        ├───MsgMgrClient
        │       CMakeLists.txt
        │
        └───MsgMgrServer
                CMakeLists.txt


C:\>NurErstenOrdnerVerarbeiten.cmd
DONE

Verarbeitet wurden:
C:\MyWorkspace\Src\MsgMgr\
C:\MyWorkspace\Src\MsgMgr2\MsgMgrClient\
C:\MyWorkspace\Src\MsgMgr2\MsgMgrServer\

C:\>

Kurze Erklärung zum Ablauf:

Zum Nachvollziehen des Ablaufs könntest Du in der ersten Zeile das "echo off" in ein "echo on" ändern (und ggf die entstandene Ausgabe posten).

Grüße
bastla

P.S.: Bitte zum Posten von Code (oder auch zB der Ausgabe des Batches) <code> und </code>-Tags verwenden.
Mehr von Mario.SteinbergMario.SteinbergWelche und wieviele Lizenzen (CAL) werden benötigt? (Windows Server 2003 mit MS SQL Server 2008)Mario.Steinberg - 3 KommentareMario.SteinbergSMBv2 in Windows 7 - Windows XP - Windows Server 2003 Domäne deaktivierenMario.Steinberg - 4 KommentareMario.SteinbergPsExec (Remote auf Win7) liefert Invalid Handle bei zweitem AufrufMario.Steinberg - 4 KommentareMario.SteinbergWinXP unterschiedliche Auflösungen bei NVIDIA Systemsteuerung uns Windows Anzeige EinstellungenMario.Steinberg - 1 Kommentar
Heiß diskutiert
FohnbitNetzwerkgerät im Netzwerk verschwindet nach NeustartFohnbit - 34 KommentarecseLaufwege erfassen in großer Hallecse - 20 Kommentaresuperfun2k24SSL VPN an Sophos UTM sehr langsamsuperfun2k24 - 16 Kommentareprplemk2Testumgebung bauen (Grundlegend)prplemk2 - 15 KommentareFrontierAbsicherung eines privaten GastnetzesFrontier - 14 KommentareadmtechEntwicklertagebuch: Release 6.4 - Filteradmtech - 13 KommentareaufdemmarsHP Z620 USB hat kein Strom beim Startenaufdemmars - 13 KommentareYan2021Nachricht an mehrere PCs im Netzwerk sendenYan2021 - 12 Kommentareuser217Kaufberatung Hardware - Hyper-V Cluster 3 Nodesuser217 - 12 KommentareMegaadwwhWireguard tunnel kann nicht hergestellt werdenMegaadwwh - 11 KommentareManuManu2021Verpasster Anruf von +49-030-123456 mit einer Mobilfunk Prepaid SIMManuManu2021 - 11 KommentareZZaaiiggaaEDIFACT - Keins vorhanden ?ZZaaiiggaa - 11 Kommentare