berner
Goto Top

CMD: for mit dir verstümmeln das Resultat, falls Blanks darin vorkommen

Hallo
Unter Windows 10 Pro
Ich möchte meinen 20 seitigen CMD Quellcode etwas kürzen und bin dabei auf folgendes Problem gestossen:
Wenn ich beim Command Prompt
dir /b /s "C:\batchfiles\Versuchs Ordner eins" eintippe erhalte ich alle Pfade, wo der gesuchten Ordner gefunden wurde und zwar mit eventuell vorkommenden Blanks.
Also als Resultat, z.B. wenn der Ordner zwei Mal vorkommt
C:\batchfiles\Versuche\Versuchs Ordner eins
C:\batchfiles\Versuche\Versuchsordner\Versuchs Ordner eins

Dabei würde mir der erst gefundene Pfad als Resultat genügen.

Wenn ich in einer Batchdatei den folgenden Skript verfasse, erhalte ich als Resultat in der Variablen zwar genau nur den ersten gefundenen Pfad, aber der Ordnername wird vor dem ersten Blank abgeschnitten:
for /f %%i in ('dir /b /s "C:\batchfiles\Versuchs Ordner eins"') do (
set Resultat=%%i
)
Ergibt:
C:\batchfiles\Versuche\Versuchs

Mit dem Parameter "usebackq" habe ich keinen Erfolg, ebenso mit den zur Verfügung stehenden Parameter des dir-Befehls.
Kann der for-Befehl mit einem folgenden dir so abgeändert werden, dass in der Variable der vollständige Pfad abgelegt wird?

Über Umwege ist das auch möglich, wenn in der Resultat-Variablen der String <Versuchs> mit <Versuchs Ordner eins> (%Suchordner%) ausgetauscht wird, z.B. mit

set Resultat=%Resultat:Versuchs=Versuchs Ordner eins%. Das Ersetzen der beiden Strings links und rechts vom Gleichheitszeichen mit entsprechenden Variablen geht aber nicht, so dass man eher die Resultat-Variable ergänzt mit set / f tokens=2* vom Suchordner, also mit <Ordner eins>

Aber die kürzeste und einfachste Lösung ist meistens die beste Lösung

Vielen Dank für eure Tipps

Content-ID: 643020

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

Ausgedruckt am: 08.11.2024 um 15:11 Uhr

Friemler
Friemler 21.01.2021 aktualisiert um 16:56:48 Uhr
Goto Top
Hallo @Berner,

wenn Du öfter (und viel) Batchscript-Code schreibst, solltest Du Dich intensiv mit der FOR-Schleife beschäftigen, um das grundlegende Konzept vor allem von FOR /f zu verstehen (Stichwörter: Tokens und Trennzeichen/Delimiters).

Schau mal in das Kapitel Die Mehrzweck-Variante, FOR /F meines Tutorial zur FOR-Schleife rein, da solltest Du die Lösung finden. Ich könnte sie Dir auch vorkauen, Du lernst aber nur etwas, wenn Du selbst drauf kommst.

Grüße
Friemler
Berner
Berner 21.01.2021 um 17:01:57 Uhr
Goto Top
Vielen Dank Friemler
Habe gesehen, dass Du das Problem umfangreich beschreibst. Werde es im Verlauf des frühen Abends genau studieren. Melde mich nochmals!
Gruss
Berner / Nicolas
Berner
Berner 21.01.2021 um 21:23:23 Uhr
Goto Top
Hallo Friemler
Habe mir Dein umfangreiches Tutorial zur Brust genommen. Dabei bin ich auf eine (fast) Lösung gestossen. Fast, weil ich in der Variablen nicht das erst Gefundene sondern das zweit Gefundene vorfinde.

for /f "delims=" %%f in ('dir /b /s "C:\batchfiles\Versuchs Ordner eins"') do echo=%%f
Diese Zeile in einer Batchdatei ergibt alle gefundenen Ordner in der folgenden Reihenfolge:
C:\batchfiles\Versuche\Versuchs Ordner eins
C:\batchfiles\Versuche\Versuchsordner\Versuchs Ordner eins

for /f "delims=" %%f in ('dir /b /s "C:\batchfiles\Versuchs Ordner eins"') do set Resultat=%%f
Diese Zeile in einer Batchdatei ergibt den zweit gefundenen Ordner:
C:\batchfiles\Versuche\Versuchsordner\Versuchs Ordner eins

Bin ich auf dem Holzweg?
Danke für Deinen Input
Friemler
Lösung Friemler 22.01.2021 um 09:58:51 Uhr
Goto Top
Hallo @Berner,

nein, kein Holzweg, Du hast schlicht noch ein Verständnisproblem. Die Schleife läuft, wie Schleifen das so machen face-wink , mehrmals durch, und zwar so lange bis alle Daten verarbeitet sind. Eine Variable, die Du in der Schleife setzt, hat nach der Schleife natürlich den zuletzt hineingeschriebenen Wert, in Deinem Fall also das letzte gefundene Verzeichnis.

Da Dich anscheinend nur das erste Verzeichnis interessiert, fallen mir zwei Optionen ein:

  1. Nach der Zuweisung an die Variable mit einem GOTO-Befehl aus der Schleife herausspringen. Das soll aber angeblich nicht gut sein, da das zu irgendwelchem Fehlverhalten des Batchscript-Interpreters führen könnte (ich persönlich habe das aber noch nicht erlebt).
  2. Du kombinierst den DIR-Befehl mit einem FINDSTR-Kommando, der die ausgegebenen Zeilen zählt. Die Zuweisung machst Du dann nur bei der ersten Zeile.

Lösung Nummer 2 sähe dann ungefähr so aus:

for /f "tokens=1* delims=:" %%a in ('dir /b /s "C:\batchfiles\Versuchs Ordner eins" ^| findstr /n "^"') do (  
  if %%~a equ 1 set "Resultat=%%~b"  
)

Die Analyse wie und warum das funktioniert überlasse ich Dir als Hausaufgabe. Tipp: Das Tutorial zur FOR-Schleife und die Hilfe zum FINDSTR-Befehl lesen.

Grüße
Friemler
Berner
Berner 23.01.2021 um 18:26:14 Uhr
Goto Top
Hallo Friemler
Vielen Dank für Deine Hilfe. Beide Vorschläge funktionierten auf Anhieb.
Ich weiss nicht was ich überlegt habe, aber auf Deine Erklärung, warum nicht das Erstgefundene in der Variablen steckt, hätte ich selber kommen müssen, da der FOR-Befehl solange Loops ausführt wie die Bedingung erfüllt ist, und somit notgedrungen das Letztgefundene in der Variable stecken wird. Das war etwas schwach von mir...
Tatsächlich wurde auch mir vor vielen Jahren an einem Programmierkurs für Datenbanken eingetrichtert, dass man Loops nicht mit einem Sprung verlassen sollte, sondern den Loop weiterlaufen lassen soll, bis die Bedingung nicht mehr erfüllt ist. Ein Verlassen mit einem Sprung sei instabil und unprofessionell und könne mit Erstellen eines vorgängigen Struktogramms (z.B. Nassi Shneiderman oder Jackson) umgangen werden. Da die Programme kompiliert wurden (*.exe) waren sie keine Stapelverarbeitungsdateien mehr und vielleicht genau deswegen anfällig für Sprünge aus Schlaufen.
Ich selber habe aber auch schon in Batchdateien im SET-Befehlein ein goto (unmittelbar nach der Variablenzuweisung) verwendet, und dabei noch nie Probleme mit dem "restlichen" Programm gehabt. Da Batchdateien top-down verarbeitet werden, glaube ich auch eher, dass ein Sprung aus einem Loop eher unschön als problematisch ist. Das ist aber nur meine Meinung...
Danke nochmals
Nicolas (Berner)
Kodiak
Kodiak 19.05.2024 um 12:54:34 Uhr
Goto Top
Hallo @Friemler und @Berner,

Option 3 unter Annahme, dass das erste gefundene Verzeichnis/Zutreffen ausgewertet werden soll
... und die Datei/Verzeichnisnamenlänge nicht <255 ist (Standard), falls doch, Wert 256 anpassen:
Find-Reihenfolge umkehren (ohne Sortierung) = 1. gefundener Treffer wird zum letzten ausgewerteten Wert:

Zitat von @Friemler:
Eine Variable, die Du in der Schleife setzt, hat nach der Schleife natürlich den zuletzt hineingeschriebenen Wert ...

for /f "tokens=*" %%a in ('dir /b /s "C:\batchfiles\Versuchs Ordner eins" ^|sort /r /+256') do set Resultat=%%a  

Ohne Parameter "/+256" wird nach ABC...0-9 bzw. CBA...9-0 sortiert und die Reihenfolge stimmt nicht mehr.

Beispiel:
testokfind1tolastwg

Gruß KoDiAk