pantherstyle
Goto Top

String abschneiden

Hallo ich möchte einen durch den Nutzer angegeben String in Form von: "set PATH=C:\Arbeitskopie\trunk" von einem Anderen String der Form: "C:\Arbeitskopie\trunk\Datenpaket\sqlDatei.sql" abschneiden so, dass ein folgender String entsteht: "Datenpaket\sqlDatei.sql" . Lässt sich das per Batch Datei erledigen? Und wenn ja wie?

Content-Key: 114236

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

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

Mitglied: 77559
77559 Apr 20, 2009 at 08:48:02 (UTC)
Goto Top
Du solltest die Systemvariable Path nur dann benutzen/ändern wenn du weißt was du tust.
set MyPath=C:\Arbeitskopie\trunk
set AndererString=C:\Arbeitskopie\trunk\Datenpaket\sqlDatei.sql
call set FolgenderString=%%AndererString:%MyPath%=%%
Member: Pantherstyle
Pantherstyle Apr 20, 2009 at 09:23:40 (UTC)
Goto Top
Tut mir Leid, aber auch nach 5 maligem durchgehen, verstehe ich die Vorgehensweise nicht. Könntest du das evtl nochmal Step by Step erklären?
Member: bastla
bastla Apr 20, 2009 at 10:17:08 (UTC)
Goto Top
@77559
Zum Ausgleich für die Vertretung im anderen Thread springe ich mal hier [Edit] etwas voreilig [/Edit] ein face-wink:

In Zeile 3 erfolgt eine Ersetzung - im String
C:\Arbeitskopie\trunk\Datenpaket\sqlDatei.sql
wird der Teil
C:\Arbeitskopie\trunk
(BTW: mit einem abschließenden "\" wär's noch besser) durch den Teil nach dem "=" (nämlich nix, da die beiden Prozentzeichen für den Ausgangsstring gelten) ersetzt - Ergebnis:
\Datenpaket\sqlDatei.sql
Die Erklärung dazu findest Du mit "set /?" als "Ersetzen von Umgebungsvariablen".

Die Schreibweise mit "call" habe ich erstmals bei Biber gesehen; alternativ (und dann vielleicht leichter nachvollziehbar) mit "delayedExpansion":
@echo off & setlocal enabledelayedexpansion
set MyPath=C:\Arbeitskopie\trunk
set AndererString=C:\Arbeitskopie\trunk\Datenpaket\sqlDatei.sql
set FolgenderString=!AndererString:%MyPath%=!
echo %FolgenderString%
Grüße
bastla
Mitglied: 77559
77559 Apr 20, 2009 at 10:21:40 (UTC)
Goto Top
Das Beispiel funktioniert aber doch bei dir?

Details stehen in der Hilfe von Set /? Wobei ich zugeben muss das der Text dort extrem knapp gefasst ist.
Das Ersetzen von Umgebungsvariablen wurde folgendermaßen erweitert:

    %PATH:str1=str2%

Dies erweitert die PATH-Umgebungsvariable, wobei jede Instanz von "str1" im erweiterten Ergebnis mit "str2" ersetzt wird. "str2" kann die leere Zeichenfolge sein, um alle Instanzen von "str1" aus der erweiterten Ausgabe zu löschen. Wenn "str1" mit einem Sternchen beginnt, steht "str1" für alles zwischen dem Anfang der erweiterten Ausgabe bis zum ersten Auftreten des übrigen Abschnitts von "str1".

In meinem Beispiel ist str1 der Inhalt einer anderen Variable nämlich MyPath str2 ist leer - es wird also gegen nichts getauscht = gelöscht.
Damit Cmd bei der Abarbeitung zuerst den Inhalt von MyPath einsetzt arbeite ich mit einem Trick der der DelayedExpansion (siehe Hilfe von cmd und/oder setlocal) gleichkommt. Der pseudo Call, denn Set ist ja kein externes Programm oder eine interne Subroutine, bewirkt mit Hilfe der verdoppelten Prozentzeichen dass die Ersetzung erst als zweiter Schritt ausgeführt wird.
Member: Pantherstyle
Pantherstyle Apr 20, 2009 at 10:44:09 (UTC)
Goto Top
So wie ich es versucht habe klappt es noch nicht aber vermutlich werdet Ihr sofort sehen warum ;D
:: Eintragung der Pfade
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filtertag.txt) DO (  
echo %%i\%%j
call set Stringteiler=%%i\%%j:%TAG_PATH%=%% >> %HELP_PATH%\tagpfade.txt
)

for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filterbranch.txt) DO (  
echo %%i\%%j
call set Stringteiler=%%i\%%j:%TAG_PATH%=%% >> %HELP_PATH%\branchpfade.txt
)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Mitglied: 77559
77559 Apr 20, 2009 at 10:57:03 (UTC)
Goto Top
Nein die Ersetzung geht nur mit normalen Variablen mit % vorne und hinten dran. Nich tmit Scheleifenvariablen und auch nicht mit Kommandozeilen Argumenten.

Aber Ich verstehe den Grund für das Splitting nicht, soll das später auf andere Laufwerke/Verzecihnisse angewendet werden?

Viel einfacher ist es wenn du Token anpasst. Du führst hier auch ständig neue uns unbekannte Variablen ein - Ich finde es extrem schwierig dir zu helfen.
Entweder Du schilderst uns dein eigentliches Problem oder Du versuchst das Schritt für Schritt zu verstehen und zu verarbeiten.
Inzwischen geht dies mMn weit über normales Helfen hinaus.

Gruß
LotPings
Member: Pantherstyle
Pantherstyle Apr 20, 2009 at 11:05:01 (UTC)
Goto Top
Die Batch funktioniert ja an sich, allerdings wurde mir aufgetragen, eine Variante ohne das Ersetzen von tokens zu kreieren. Damit aber die Syntax funktioniert, muss unbedingt der Variable Teil vor den eigentlichen Ordnern und Dateinamen eliminiert werden, da ein Vergleich der Dateinamen stattfindet. Deshalb, wenn schon die beiden Pfade z.B. c:\M_Shell\dateiname und c:\T_Shell\dateiname2 unterschiedlich sind, dann wird die Batch niemals feststellen, dass 2 Dateien gleich sind, da immer der Pfad unterschiedlich ist. Deshalb muss dieser Variable Teil weg. Das mit dem einführen neuer Variablen ist nur halb Richtig, da ich von Anfang an meinte geschildert zu haben, dass ich eine feste Variable, namens PATH (in dem Fall TAG_PATH) von einem anderen String kürzen wollte (dieser setzt sich aus %%i und%%j zusammen). Leider kann man ja innerhalb einer for-Schleife keine Pfade setzen. Ich hoffe der Fall ist nun klarer.
Member: bastla
bastla Apr 20, 2009 at 12:56:22 (UTC)
Goto Top
Hallo Pantherstyle!

Dein Code müsste auf ein Unterprogramm zurückgreifen. Außerdem muss zuerst der Teilstring gebildet werden und erst danach kannst Du diesen in eine Datei schreiben :
:: Eintragung der Pfade
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filtertag.txt) DO (  
    echo %%i\%%j
    call :GetRelPath "%%i\%%j" "%TAG_PATH%"  
)
echo %RelPath%>>%HELP_PATH%\tagpfade.txt

for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filterbranch.txt) DO (  
    echo %%i\%%j
    call :GetRelPath "%%i\%%j" "%TAG_PATH%"  
)
echo %RelPath%>>%HELP_PATH%\branchpfade.txt
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


goto :eof

:GetRelPath
set "Full=%~1"  
set "Part=%~2"  
call set "RelPath=%%Full:%Part%=%%"  
goto :eof
[Edit] Unnötige Überlegungen zur Zerlegung entfernt ... /Edit]
Ansonsten noch ein Hinweis: Das Zerlegen eines Pfades in die Bestandteile "Laufwerk" ("drive"), "Pfad" ("path"), "Dateiname" ("name") und "-typ" ("extension") kannst Du so durchführen:
for /f "delims=" %%i in (%HELP_PATH%\filtertag.txt) do (  
    echo %%~di
    echo %%~pi
    echo %%~ni
    echo %%~xi
    REM und als Kombination
    echo %%~nxi
)
Näheres dazu gegen Ende von "for /?" ...

Grüße
bastla
Member: Pantherstyle
Pantherstyle Apr 23, 2009 at 09:15:07 (UTC)
Goto Top
Hallo,
sorry dass ich mich länger nicht gemeldet habe (viel zu tun).
Ich habe deine Version getestet (ohne Erfolg) und darauf meine Eigene Verison aufgebaut (auch ohne Erfolg):

echo off
:: Veränderbar durch den Benutzer
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Eingabe der Pfade
set TAG_PATH=C:\Arbeitskopie\trunk\M_SHELL_20090402
set BRANCH_PATH=C:\Arbeitskopie\trunk\T_Shell20090403
set HELP_PATH=C:\Arbeitskopie\Hilfsordnerbflexxdateien
set WORK_PATH=C:\Arbeitskopie\trunk\Daten\SoftwarePaket\Batch-Dateien
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: Eintragung der Pfade
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /F "skip=2 tokens=1* delims=\" %%i IN (%HELP_PATH%\filtertag.txt) DO call :sub1 %%i %%j %TAG_PATH% %HELP_PATH%  
echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for /F "skip=2 tokens=1* delims=\" %%i IN (%HELP_PATH%\filterbranch.txt) DO :sub2 %%i %%j %BRANCH_PATH% %HELP_PATH%  
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

goto :eof

:sub1
set BASIC_PATH=%1\%2
set TAG_PATH=%3
set HELP_PATH=%4
call set Stringteiler=%TAG_PATH%:%BASIC_PATH%=%% >> %HELP_PATH%\tagpfade.txt
goto :eof

:sub2
set BASIC_PATH=%1\%2
set BRANCH_PATH=%3
set HELP_PATH=%4
call set Stringteiler=%BRANCH_PATH%:%BASIC_PATH%=%% >> %HELP_PATH%\branchpfade.txt
goto :eof

Ich nehme an, es hängt mit der Syntax call set Stringteiler Zusammen, doch inwiefern?
Member: Pantherstyle
Pantherstyle Apr 27, 2009 at 06:20:16 (UTC)
Goto Top
Hallo,
die Frage ist noch präsent und ich wollte sie nur noch mal ins Gedächtnis zurück hohlen.

Hier nochmal der aktualisierte Code:
echo off
:: Veränderbar durch den Benutzer
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Eingabe der Pfade
set TAG_PATH=C:\Arbeitskopie\trunk\M_SHELL_20090402
set BRANCH_PATH=C:\Arbeitskopie\trunk\T_Shell20090403
set HELP_PATH=C:\Arbeitskopie\Hilfsordnerbflexxdateien
set WORK_PATH=C:\Arbeitskopie\trunk\Daten\SoftwarePaket\Batch-Dateien
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


:: Ausgabe der Nutzerangaben
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo TAG Pfad   : %TAG_PATH%
echo SchemaTag Pfad   : %TAG_PATH_STRKT%
echo Branch Pfad: %BRANCH_PATH%
echo SchemaBranch Pfad: %BRANCH_PATH_STRKT%
echo Hilfe Pfad: %HELP_PATH%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


:: Vorbereitung der Verarbeitung
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
rd %HELP_PATH% /s /q
mkdir %HELP_PATH%
cd %TAG_PATH%
dir > %HELP_PATH%\indextag.txt /B /S /O-g
cd %BRANCH_PATH%
dir > %HELP_PATH%\indexbranch.txt /B /S /O-g

:: Herausfiltern der .sql Dateien
find /V "svn" %HELP_PATH%\indextag.txt > %HELP_PATH%\filtertag.txt  
find /V "svn" %HELP_PATH%\indexbranch.txt > %HELP_PATH%\filterbranch.txt  

:: Löschen der Mittlerdateien
del %HELP_PATH%\indextag.txt
del %HELP_PATH%\indexbranch.txt
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: Eintragung der Pfade
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filtertag.txt) DO call :sub1 %%i %%j %TAG_PATH%  
for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filterbranch.txt) DO call :sub2 %%i %%j %BRANCH_PATH%  
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Neue Dateien
for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\branchpfade.txt) DO (  
echo %%i\%%j
findstr "%%j" %HELP_PATH%\tagpfade.txt  
if ERRORLEVEL 1 echo %%i\%%j >> %HELP_PATH%\neu.txt
)
:: Vorhandene Dateien
for /F "skip=4 tokens=1* delims=\" %%i IN (%HELP_PATH%\tagpfade.txt) DO (  
echo %%i\%%j
findstr "%%j" %HELP_PATH%\branchpfade.txt  
if not ERRORLEVEL 1 echo %%i\%%j >> %HELP_PATH%\vorhanden.txt
)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:: Erfassung von veraenderten Dateien
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /F "tokens=1*" %%i IN (%HELP_PATH%\vorhanden.txt) DO (  
echo %%i

fc %TAG_PATH%\%%i %BRANCH_PATH%\%%i
if ERRORLEVEL 1 echo %%i >> %HELP_PATH%\veraendert.txt
)
goto eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:sub1
set BASIC_PATH=%1\%2
set TAG_PATH=%3
echo %BASIC_PATH%
call set Stringteiler=%BASIC_PATH%:%TAG_PATH%=%% >> %HELP_PATH%\tagpfade.txt
goto :eof

:sub2
set BASIC_PATH=%1\%2
set BRANCH_PATH=%3
echo %BASIC_PATH%
call set Stringteiler=%BASIC_PATH%:%BRANCH_PATH%=%% >> %HELP_PATH%\branchpfade.txt
goto :eof
Mitglied: 77559
77559 Apr 27, 2009 at 08:37:10 (UTC)
Goto Top
Zitat von @Pantherstyle:
Hallo,
die Frage ist noch präsent und ich wollte sie nur noch mal ins Gedächtnis zurück hohlen.

Hallo Pantherstyle,
die Sammlung an Codestücken wächst, aber weder ist deine Aufgabenstellung ganz klar noch ist dein Feedback ausreichend.
Es funktioniert nicht, hilft Niemand.
Welches Ergebnis erwartest Du mit Beispieldaten vorher + nachher.

allerdings wurde mir aufgetragen, eine Variante ohne das Ersetzen von tokens zu kreieren.
Das verstehe ich jetzt überhaupt nicht. Ist das eine Übungsaufgae? Dann knie dich selber rein, so lernt man Besten.

"Tokens" sind ein Bestandteil des For /F Befehls und dienen der Bestimmung welche der durch "Delmis" getrennten Elemente weiterverwendet werden sollen. Siehe For /F

Gruß
LotPings
Member: Pantherstyle
Pantherstyle Apr 27, 2009 at 08:51:49 (UTC)
Goto Top
Die Verarbeitung / Funktion der Tokens kenne ich ja. Das mit dem Auftrag tokens nicht zu verwenden resultiert daraus, das auch Andere mein Programm verwenden sollen und zur vermeidung von Fehlern sollen nur die Pfade angegeben werden. Die Ausgabe des Programms meinte ich schon beschrieben zu haben nämlich:

Pfad A
C:\ÜberOrdner\Unterüberordner\

Pfad B
C:\ÜberOrdner\UnterÜberOrdner\UnterOrdner\Datei

sollen in
Pfad C
UnterOrdner\Datei

unmgewandelt werden, da die Dateipfade später nach diesem Muster verarbeitet/verglichen werden.
Member: Biber
Biber Apr 27, 2009 at 09:35:30 (UTC)
Goto Top
Moin Pantherstyle,

ich kann LotPings Eindruck nur bestätigen - die eingangs genannte Aufgabenstellung korrespondiert wenig bis gar nicht mit Deinen geposteten Schnipseln und die Lösungsstrategien in den Antworten scheinst Du zu überlesen.

Auch ich habe wenig Anlass zur Hoffnung, dass mein Kommentar von Dir berücksichtigt wird, aber diesen letzten Versuch mache ich noch.

bastla und LotPings haben doch oben eine Lösung gepostet, die Du, ich, wir alle jederzeit am CMD-Prompt verifizieren könnten:
[Eingegebene Zeilen mit ">" gekennzeichnet]
>set "pfadA=C:\ÜberOrdner\Unterüberordner"  
>set "pfadB=C:\ÜberOrdner\UnterÜberOrdner\UnterOrdner\Datei"  
>call echo Stringteiler=%PfadB:%PfadA%=%
Stringteiler=\UnterOrdner\Datei
---> Das würde also klappen, wenn Du es direkt in Deine "branchpfade schreiben lässt OHNE SET und OHNE das "Stringteiler=", aber WTF soll denn passieren bei Deinem
Set Stringteiler=... >>branchpfade.txt"
???
>set something=whatever>bla.txt
>type bla.txt

>
...da der "Set var=wert"-Befehl keine Ausgabe erzeugt wird auch nie etwas Brauchbares in der "branchpfade.txt" stehen.
Und die Variable %Stringteiler% verwendest Du ja auch nicht -- was also ist Deine Erwartungshaltung???

Abgesehen davon - IMHO ist es sinnvoller, diese ganze SVN-Workspace-Ein-und-Auscheckerei so zu machen wie 283.000 andere User auch:
  • Definiert auf den Clients mit dem SUBST-Befehl ein Laufwerk T: wie "trunk" oder "team"
SUBST T: C:\Arbeitskopie\trunk
...dann hast Du Deinen so genannten "Restpfad" immer richtig.

Grüße
Biber
Member: Pantherstyle
Pantherstyle Apr 27, 2009 at 11:25:57 (UTC)
Goto Top
Hallo,
es funktioniert jetzt. Mir ist aufgefallen, dass ich bei meinen Versuchen immer einen Fehler (wie mir schien) verändert zu haben.
Ich habe aus %%Pfad:%PfadA%=%%
immer %Pfad%:%PfadA%=%%
gemacht, wodurch eine Ausgabe wie die folgende Zustande kam:
C:\Arbeitskopie\trunk:C:\Arbeitskopie\trunk\Unterordner\Datei

Danach habe ich jetzt einfach ALLES BLIND übernommen und herumexperimentiert. Dabei ist mir aufgefallen, das außerhalb der Subroutine die oben gezeigte Ausgabe kam, aber innerhalb der Subroutine das gewünschte Ergebnis vorlag. Der folgende Algorythmus geht jetzt:
:: Eintragung der Pfade
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filtertag.txt) DO (  
    echo %%i\%%j
    call :GetTagRelPath "%%i\%%j" "%TAG_PATH%"  
)

for /F "tokens=1* delims=\" %%i IN (%HELP_PATH%\filterbranch.txt) DO (  
    echo %%i\%%j
    call :GetBranchRelPath "%%i\%%j" "%BRANCH_PATH%"  
)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


goto :eof

:GetTagRelPath
set "Full=%~1"  
set "Part=%~2"  
call set "RelPath=%%Full:%Part%=%%"  
echo %RelPath% >>%HELP_PATH%\branchpfade.txt
goto :eof

:GetBranchRelPath
set "Full=%~1"  
set "Part=%~2"  
call set "RelPath=%%Full:%Part%=%%"  
echo %RelPath% >>%HELP_PATH%\tagpfade.txt
goto :eof

Danke an ALLE die geholfen haben. Besonderen Dank an die, die die Nerven nicht verloren haben ;D