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
GELÖST

PATH-Variable zerlegen und durchsuchen

Frage Entwicklung Batch & Shell

Mitglied: Smithy69123

Smithy69123 (Level 1) - Jetzt verbinden

23.03.2011 um 17:00 Uhr, 5950 Aufrufe, 6 Kommentare

Zerlegen der %PATH%-Systemvariable und gleichzeitiges Durchsuchen der jeweiligen Teilstrings

Hallo zusammen,

Ich beschäftige mich jetzt seit circa einer Woche tiefer mit Batch-Dateien und habe mittlerweile ein recht ansehnliches Programm hinbekommen.
Dabei habe ich mir jede Menge Tipps und Beiträge aus diesem Forum zunutze gemacht, weshalb ich mir sicher bin dass auch mein Problem zu
den schnell löslichen zählt wenn man sich etwas besser auskennt.

Mein Problem:

Ich möchte die Systemvariable %PATH% zerlegen und mir den Teilstring, wenn er einen bestimmten Teil einer Pfadangabe enthält, sichern.
Der letzte Teil des Pfads soll dann noch entfernt werden sowie die Schleife verlassen werden. Dies ist bei meinem derzeitigen Konstrukt jedoch
das Hauptproblem. Ich kann innerhalb meiner Schleife nicht auf die Variable "PFAD" zurückgreifen, ein "set PFAD" zeigt mir jedoch deren Inhalt korrekt an.

Mein Pseudocode:
01.
beginn der schleife 
02.
zerlege PATH bei ";" in TEIL 
03.
durchsuche TEIL auf "\ora92\bin\" 
04.
wenn enthalten setze PFAD = TEIL 
05.
wenn "%PFAD%\sqlplus.exe\" existiert verlasse Schleife 
06.
ende der schleife 
07.
 
08.
entferne "bin\" von PFAD
Soweit mein Vorhaben. Jetzt kommt mein Quellcode.
Ich bin mir sicher dass er alles andere als sauber programmiert ist, aber mehr kriege ich noch nicht auf die Kette.
Ich bin soweit dass der richtige TEIL der Variable PFADzugewiesen wird. Jedoch kriege ich die Abbruchbedingung nicht hin, da PFAD angeblich keinen Wert
hat. Weiterhin wird PATH nicht nur beim Trenn- sondern auch beim Leerzeichen getrennt. Das ist jedoch ersteinmal nebensächlich.

01.
@echo off 
02.
@echo off 
03.
:: 
04.
For /f "delims=; tokens=*" %%a in ("%path%") do for %%1 IN (%%a) DO ( 
05.
 
06.
echo "%%1" | @find /I /C "ora92\bin" > nul 
07.
if not errorlevel == 1 set pfad=%%1  
08.
::Dieser Abbruch wird nicht ausgeführt, da %pfad% anscheinend erst nach der Schleife einen Wert erhält 
09.
if exist "%pfad%\sqlplus.exe" goto :erfolg 
10.
11.
 
12.
echo Pfad nicht gefunden! 
13.
pause 
14.
goto :eof 
15.
 
16.
:erfolg 
17.
echo Pfad gefunden! 
18.
::Hier sollte er jetzt noch das "bin" vom Pfad entfernen 
19.
set pfad 
20.
pause 
21.
goto :eof 
22.
 
23.
:eof
Ich hoffe dass mein Vorhaben halbwegs verständlich geblieben ist, wenn nicht fragt gerne nach.


Vielen Dank schonmal,


Smithy69123
Mitglied: bastla
23.03.2011 um 17:14 Uhr
Hallo Smithy69123 und willkommen im Forum sowie als Batcher!

Dass %pfad% innerhalb der Schleife zwar einen Wert erhält, dieser aber nicht ausgelesen wird, ließe sich zwar per "delayedExpansion" ändern - allerdings brauchst Du diese Variable (zwischendurch) ja eigentlich genauso wenig wie die zweite "for"-Schleife (die bei Pfaden mit Leerzeichen im Namen ja sogar kontraproduktiv wäre) - es sollte doch auch (ungetestet)
for /f "delims=; tokens=*" %%a in ("%path%") DO echo %%a|find /i "\ora92\bin">nul && (set "Pfad=%%~a" & if exist "%%~a\sqlplus.exe" goto :erfolg)
genügen - wobei ich allerdings den Sprung aus der Schleife vermeiden und daher etwa so vorgehen würde:
01.
set "Pfad=" 
02.
for /f "delims=; tokens=*" %%a in ("%path%") do for %%1 IN (%%a) DO echo %%a|find /i "\ora92\bin">nul && if exist "%%~a\sqlplus.exe" set "Pfad=%%~a" 
03.
if not defined Pfad echo Pfad nicht gefunden! & pause & goto :eof 
04.
echo Pfad gefunden!
Hinsichtlich des Entfernens von "\bin": Wie soll das Ergebnis weiter verwendet werden, bzw stört ein "\" am Ende des gekürzten Pfades?

Grüße
bastla
Bitte warten ..
Mitglied: Smithy69123
23.03.2011 um 18:11 Uhr
Hallo,
erst einmal vielen Dank für die schnelle Antwort.
Da ich mich mittlerweile nach Hause bewegt habe musste ich das ganze mal etwas abändern. Ich suche statt "\ora92\bin" jetzt einfach nach "\system32" und prüfe statt der Existenz von "\sqlplus.exe" mal auf die von "\ping.exe".

Dein zweiter Vorschlag hat mir schon ein ganzes Stück weitergeholfen und ist auch deutlich übersichtlicher als dieser Würfelhusten, den ich da fabriziert habe.
Nur in der zweiten Schleife war ein kleiner Fehler, aber den habe ich mittlerweile auch entdeckt: Statt der Angabe %%~a muss in der inneren Schleife %%~1 verwendet werden. So sieht der Code dann jetzt aus:
01.
set "Pfad="  
02.
for /f "delims=; tokens=*" %%a in ("%path%") do for %%1 IN (%%a) DO echo %%1|find /i "\system32">nul && if exist "%%~1\ping.exe" set "Pfad=%%~1" 
03.
if not defined Pfad echo Pfad nicht gefunden! & pause & goto :eof  
04.
echo Pfad gefunden! & set pfad & pause 
05.
:eof
Aber wenn man sich %%1 vor der Übergabe an das find-Kommando durch ein echo ausgeben lässt bemekt man immernoch die Trennung bei Leerzeichen im Dateipfad. Beim system32-Pfad kommen ja keine vor, hier wird der Pfad bereits einwandfrei ausgelesen.
Ein "\" am Ende des gekürzten Pfads stört übrigens nicht, ist sogar erwünscht. Aber mir fielen hier jetzt nur Varianten ein, die ungefähr so komplex waren wie mein Anfangscode und dabei die Flexibilität einer Stahlbetondecke mit sich gebracht haben.

Dankeschön,

Smithy69123
Bitte warten ..
Mitglied: bastla
23.03.2011 um 19:01 Uhr
Hallo Smithy69123!

Sorry - vergiss gleich mal, was ich da oben produziert respektive gepasted habe ...

Die Zeile 2 sollte eigentlich einfach so aussehen:
for %%a in ("%path:;=";"%") do echo %%a|find /i "\ora92\bin">nul && if exist "%%~a\sqlplus.exe" set "Pfad=%%dp~a"
Hintergrund: Da eine "gewöhnliche" "for"-Schleife auch anhand von ";" trennt, muss nur dafür gesorgt werden, dass Pfade mit Leerzeichen nicht "zerrissen" werden - daher einfach alle Semikola durch ";" ersetzen und am Anfang und Ende auch jeweils ein Anführungszeichen ergänzen - dann enthält %%a jeweils einen Pfad unter Anführungszeichen und daher komplett.

Da sich dann der Pfad schon in der Schleifenvariablen befindet, kann auch gleich "bin" eliminiert werden, indem nur Laufwerk und Pfad verwendet werden (soferne sich nicht am Ende des "path"-Eintrages schon ein "\" befindet) - ansonsten die "Sicherheitsvariante":
01.
for %%a in ("%path:;=";"%") do echo %%a|find /i "\ora92\bin">nul && if exist "%%~a\sqlplus.exe" set "Pfad=%%~a" 
02.
if not defined Pfad echo Pfad nicht gefunden! & pause & goto :eof 
03.
if "%Pfad:~-1%"=="\" set "Pfad=%Pfad:~0,-1%" 
04.
for %%a in ("%Pfad%") do set "Pfad=%%~dpa"
Noch kurz zur Erklärung von "%%~dpa": Wie am Ende der Hilfe zu "for" nachzulesen, wird mit "d" das Laufwerk ("drive") und mit "p" der Pfad ("path") aus dem Inhalt von %%a extrahiert - dabei wird alles vom Beginn bis zum letzten "\" (inklusive) als Laufwerk + Pfad interpretiert (alles danach als Name + Extension). Wenn nun der gefundene Pfad am Ende einen "\" aufweist, würde diese Zerlegung keinen Erfolg haben (weil ja 'alles bis zum letzten "\"' verwendet wird) - daher muss vorweg ein abschließender "\" abgeschnitten werden - Infos dazu gibt's per "set /?" ...

Grüße
bastla
Bitte warten ..
Mitglied: Smithy69123
23.03.2011 um 19:53 Uhr
Hallo bastla,

ich muss zwar zugeben dass ich den Teil mit dem Ersetzen nicht mehr ganz verstanden habe, aber es funktioniert einwandfrei.
Es ist (wenn ich das nach anderthalb Wochen schon sagen darf ) immer wieder überraschend was dieser for-Befehl noch so alles kann. Den Teil mit ~dp hatte ich auch schon entdeckt. Aber das hier "%path:;=";"%" werde ich mir auf jeden Fall noch mal zu Gemüte führen müssen.

Vielen Dank für deine schnelle und gute Hilfe.

Smithy69123
Bitte warten ..
Mitglied: bastla
23.03.2011 um 19:58 Uhr
Hallo Smithy69123!

Die schnelle Hilfe war leider nicht gut ...

Zum Ersetzen wirst Du auch mit "set /?" fündig, und bei weiteren Fragen: fragen ...

Grüße
bastla
Bitte warten ..
Mitglied: Biber
23.03.2011 um 21:09 Uhr
Moin Smithy69123,

willkommen im Forum auch von mir.

Wenn du dich doch ohnehin gerade spielerisch an die schlichte Eleganz der FOR-Anweisung herantastest,
dann spendier ich noch zwei Oneliner vom CMD-Prompt, um andere Strategien aufzuzeigen.

[Am CMD-Prompt; führendes ">" nicht mit eingeben, ist sich mein Prompt]
(=21:03:04  D:\temp=) 
>@for %i in ("%path:;=";"%") do @If exist "%i\sqlplus.exe" @echo %~dpi|findstr /i "ora" 
C:\Oracle\Home\10.2\ 
 
 
(=21:03:14  D:\temp=) 
>for %i in (sqlplus.exe) do @for %j in (%~dp$PATH:i..\) do @echo %~dpj|findstr /i "ora" 
C:\Oracle\Home\10.2\
Die erste Variante sucht "nur" nach der sqlplus.exe im Pfad... der Pfad darüber (also oberhalb ....\bin\)
steht in dem "echo %~dpi" und kann gefiltert werden nach "ora92" bei dir, nach "ora" bei mir.
Ansonsten ist es genau der Weg, den bastla oben verwendet hat.

Die zweite Variante finde ich etwas charmanter.. die bedient sich der eher seltener verwendeten %~dp$PATH:i-Syntax.

Das Geheimnis beim Bätchen ist: Nicht soviel Heckmeck drum machen.

Grüße
Biber
Bitte warten ..
Neuester Wissensbeitrag
CPU, RAM, Mainboards

Angetestet: PC Engines APU 3a2 im Rack-Gehäuse

(1)

Erfahrungsbericht von ashnod zum Thema CPU, RAM, Mainboards ...

Ähnliche Inhalte
Batch & Shell
gelöst Selected Gridview Value in Variable schreiben (4)

Frage von reissaus73 zum Thema Batch & Shell ...

Batch & Shell
gelöst Batch Abfrage Vergleiche mit Variable goto (4)

Frage von Zunaras zum Thema Batch & Shell ...

Batch & Shell
Variable setzen können während timeout (3)

Frage von DontFlameMeITryMyBest zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Grafikkarten & Monitore
Win 10 Grafikkarte Crash von Software? (13)

Frage von Marabunta zum Thema Grafikkarten & Monitore ...

DSL, VDSL
DSL-Signal bewerten (13)

Frage von SarekHL zum Thema DSL, VDSL ...

Switche und Hubs
Trunk für 2xCisco Switch. Wo liegt der Fehler? (9)

Frage von JayyyH zum Thema Switche und Hubs ...

Backup
Clients als Server missbrauchen? (8)

Frage von 1410640014 zum Thema Backup ...