Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Verzeichniswechsel aus For-Schleife heraus

Frage Entwicklung

Mitglied: Mario.Steinberg

Mario.Steinberg (Level 1) - Jetzt verbinden

16.03.2010 um 12:48 Uhr, 2568 Aufrufe, 13 Kommentare

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!

01.
@echo off & setlocal enabledelayedexpansion 
02.
 
03.
set WORKSPACE=C:\MyWorkspace 
04.
set TARGET_DIR=D:\WorkspaceNeu 
05.
 
06.
pushd . 
07.
cd /D %WORKSPACE% 
08.
 
09.
for /f "delims=" %%i in ('dir /s /b "CMakeLists.txt"') do (  
10.
    set "RelPath=%%i"  
11.
    set "RelPath=!RelPath:%WORKSPACE%\=! 
12.
    set "RelPath=!RelPath:\CMakeLists.txt=! 
13.
    if not exist %TARGET_DIR%\!RelPath! mkdir %TARGET_DIR%\!RelPath! 
14.
    pushd . 
15.
    cd /D %TARGET_DIR%\!RelPath! 
16.
    %CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt 
17.
    popd 
18.
19.
popd 
20.
pause 
21.
:END 
22.
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
Mitglied: bastla
16.03.2010 um 13:26 Uhr
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":
01.
pushd "%TARGET_DIR%\!RelPath!" 
02.
%CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt 
03.
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):
01.
set "RelPath=%%~dpi" 
02.
set "RelPath=!RelPath:%WORKSPACE%\=!
Dass sich am Ende von !RelPath! dadurch noch ein "\" befindet, kannst Du zur Not auch ignorieren ...

Grüße
bastla
Bitte warten ..
Mitglied: Mario.Steinberg
16.03.2010 um 14:22 Uhr
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.

01.
pushd .  
02.
cd /D %TARGET_DIR%\!RelPath!  
03.
%CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt  
04.
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!?
Bitte warten ..
Mitglied: bastla
16.03.2010 um 15:03 Uhr
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 ) ...

... 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
Bitte warten ..
Mitglied: Mario.Steinberg
16.03.2010 um 15:31 Uhr
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.
Bitte warten ..
Mitglied: bastla
16.03.2010 um 16:16 Uhr
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
Bitte warten ..
Mitglied: Mario.Steinberg
17.03.2010 um 08:17 Uhr
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

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

01.
%CMAKE_CMD% -G %CMAKE_GENERATOR%  %WORKSPACE%\!RelPath!\CMakeLists.txt 
war mist. Warum acuh immer funktioniert es so

01.
%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
Bitte warten ..
Mitglied: bastla
20.03.2010 um 11:41 Uhr
Hallo Mario.Steinberg!

Mit Verspätung (und noch dazu nur oberflächlich getestet) :
01.
@echo off & setlocal enabledelayedexpansion 
02.
 
03.
set WORKSPACE=C:\MyWorkspace 
04.
set TARGET_DIR=D:\WorkspaceNeu 
05.
set "Done=%temp%\Done.txt" 
06.
 
07.
pushd %WORKSPACE% 
08.
copy nul "%Done%">nul 
09.
for /f "delims=" %%i in ('dir /s /b "CMakeLists.txt"') do (  
10.
    echo %%~fi|findstr /L /G:"%Done%">nul 2>nul || ( 
11.
        set "RelPath=%%~dpi" 
12.
        >>"%Done%" echo !RelPath! 
13.
        set "RelPath=!RelPath:%WORKSPACE%\=! 
14.
        if not exist %TARGET_DIR%\!RelPath! mkdir %TARGET_DIR%\!RelPath! 
15.
        pushd %TARGET_DIR%\!RelPath! 
16.
        %CMAKE_CMD% -G %CMAKE_GENERATOR% %WORKSPACE%\!RelPath! 
17.
        popd 
18.
19.
20.
popd 
21.
 
22.
:END 
23.
echo DONE 
24.
echo\ 
25.
echo Verarbeitet wurden: 
26.
type "%Done%" 
27.
pause
Grüße
bastla
Bitte warten ..
Mitglied: Biber
20.03.2010 um 12:12 Uhr
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
Bitte warten ..
Mitglied: bastla
20.03.2010 um 13:01 Uhr
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
Bitte warten ..
Mitglied: Biber
20.03.2010 um 13:13 Uhr
[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.

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

Grüße
bastla
Bitte warten ..
Mitglied: Mario.Steinberg
22.03.2010 um 14:37 Uhr
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

</code>
...
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%=!
)
)
popd

:END
echo DONE
echo\
echo Verarbeitet wurden:
type "%Done%"
</code>

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
echo %%~fi|findstr /L /G:"%Done%">nul 2>nul || (
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
Bitte warten ..
Mitglied: bastla
22.03.2010, aktualisiert 18.05.2014
Hallo Mario.Steinberg!
Ich versuche mal zu verstehen, was genau
echo %%~fi|findstr /L /G:"%Done%">nul 2>nul || (
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:
In der Datei %Done% entsteht eine Liste der Ordner, welche verarbeitet wurden (wird zunächst leer erstellt). Für jede gefundene "CMakeLists.txt" wird durch die angeführte Zeile der vollständige Pfad (%%~fi) ausgegeben und verglichen (findstr /L /G:), ob einer der Listeneinträge (= eine der Zeilen in %Done%) in diesem Pfad enthalten ist. Da nur das Ergebnis des Vergleiches interessiert, werden keine Ausgaben getätigt (>nul 2>nul). Ist keiner der Pfade aus %Done% im aktuellen Pfad enthalten (||, werden die folgende (geklammerten) Zeilen ausgeführt (und dabei ua der Pfad zu dieser verarbeiteten "CMakeLists.txt" in die Liste aufgenommen ...

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.
Bitte warten ..
Neuester Wissensbeitrag
Windows 10

Powershell 5 BSOD

(1)

Tipp von agowa338 zum Thema Windows 10 ...

Ähnliche Inhalte
Batch & Shell
gelöst CMD: icacls in for-Schleife (2)

Frage von Lowrider614 zum Thema Batch & Shell ...

Batch & Shell
gelöst Batch Problem bei einer For Schleife (2)

Frage von Juergen42 zum Thema Batch & Shell ...

Batch & Shell
gelöst For Schleife kaputt? (5)

Frage von Peter32 zum Thema Batch & Shell ...

Batch & Shell
Batch: Variable Expansion in einer FOR-Schleife (9)

Frage von .Sessl zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

Outlook & Mail
Outlook 2010 findet ost datei nicht (18)

Frage von Floh21 zum Thema Outlook & Mail ...

Windows Server
Server 2008R2 startet nicht mehr (Bad Patch 0xa) (18)

Frage von Haures zum Thema Windows Server ...