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-Key: 138359

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

Printed on: April 19, 2024 at 20:04 o'clock

Member: bastla
bastla Mar 16, 2010 at 12:26:44 (UTC)
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
Member: Mario.Steinberg
Mario.Steinberg Mar 16, 2010 at 13:22:03 (UTC)
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!?
Member: bastla
bastla Mar 16, 2010 at 14:03:57 (UTC)
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
Member: Mario.Steinberg
Mario.Steinberg Mar 16, 2010 at 14:31:23 (UTC)
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.
Member: bastla
bastla Mar 16, 2010 at 15:16:16 (UTC)
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
Member: Mario.Steinberg
Mario.Steinberg Mar 17, 2010 at 07:17:38 (UTC)
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
Member: bastla
bastla Mar 20, 2010 at 10:41:25 (UTC)
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
Member: Biber
Biber Mar 20, 2010 at 11:12:08 (UTC)
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
Member: bastla
bastla Mar 20, 2010 at 12:01:44 (UTC)
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
Member: Biber
Biber Mar 20, 2010 at 12:13:44 (UTC)
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]
Member: bastla
bastla Mar 20, 2010 at 12:46:05 (UTC)
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
Member: Mario.Steinberg
Mario.Steinberg Mar 22, 2010 at 13:37:16 (UTC)
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
Member: bastla
bastla Mar 22, 2010, updated at May 18, 2014 at 16:23:50 (UTC)
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.
Hotly discussed
gleixnerdCheck of ZFW Firewallgleixnerd - 3 CommentsAlexWishaHow to set up and configure a Linux GRE tunnelAlexWisha - 3 CommentsjstrickerWIREGUARD VPN ON UDM PRO BEHIND FRITZBOX - HANDSHAKE DID NOT COMPLETEjstricker - 3 CommentsDaniEnd of Support dates for Office 2016, 2019 Apps und Productivity ServersDani - 1 Comment