Smarte Methode zum Dateipfad kürzen gesucht
Smarte Methode zum Dateipfad kürzen gesucht
Moin zusammen,
gibt es in PB eine clevere Methode (unter Windows), um von einer Verzeichnisebene (als String) die n-te übergeordnete Verzeichnisebene anzusprechen?
Angenommen ich habe das Verzeichnis D:\Obst\Äpfel\Reife\Greenstar\ ermittelt und möchte auf D:\Obst\Äpfel\Reife\ mittels Delete() oder Rename() zugreifen.
Muss ich den String dann zwingend vorher kürzen (StringField, CountString) oder gibt es sowas wie "\.." für ein Verzeichnis höher? Meine Tests in diese Richtung haben bisher leider nicht funktioniert.
Kurzer
gibt es in PB eine clevere Methode (unter Windows), um von einer Verzeichnisebene (als String) die n-te übergeordnete Verzeichnisebene anzusprechen?
Angenommen ich habe das Verzeichnis D:\Obst\Äpfel\Reife\Greenstar\ ermittelt und möchte auf D:\Obst\Äpfel\Reife\ mittels Delete() oder Rename() zugreifen.
Muss ich den String dann zwingend vorher kürzen (StringField, CountString) oder gibt es sowas wie "\.." für ein Verzeichnis höher? Meine Tests in diese Richtung haben bisher leider nicht funktioniert.
Kurzer
Zuletzt geändert von Kurzer am 08.03.2020 19:33, insgesamt 1-mal geändert.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
Re: Smarte Methode zum Dateipfad kürzen gesucht
Ohne Worte
Code: Alles auswählen
;-TOP by mk-soft ;)
Procedure.s GetParentPath(Path.s, n = 1)
For i = 1 To n
If Right(Path, 1) = #PS$
Path = Left(Path, Len(Path) - 1)
EndIf
Path = GetPathPart(Path)
Next
ProcedureReturn Path
EndProcedure
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\")
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 2)
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 3)
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 4)
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Smarte Methode zum Dateipfad kürzen gesucht
Das ist smart!
Wenn ich mir da mein Konstrukt ansehe...
Wobei ich aber auch gemischte Path-Separatoren unterstützen wollte.
Vielen Dank für dein klasse Beispiel, mk-soft.
Wenn ich mir da mein Konstrukt ansehe...
Code: Alles auswählen
EnableExplicit
Procedure.s PathPart (sPath.s, iLevelsUp.i)
#Separator = "\"
Protected.i i, iOutPathLen, iPathLen = Len(sPath), iCountLevels
Protected.s sTemp = ReplaceString(sPath, "/", #Separator)
; Pfad und übergeordnete Verzeichnisebene prüfen
If iPathLen = 0 Or iLevelsUp < 1 : ProcedureReturn sPath : EndIf
If Right(sTemp, 1) = #Separator
sTemp = Left(sTemp, iPathLen - 1)
EndIf
iCountLevels = CountString(sTemp, #Separator) + 1
; Anzahl der Unterverzeichnisse im Pfad prüfen
If iCountLevels = 1
ProcedureReturn sPath
ElseIf iLevelsUp > iCountLevels
ProcedureReturn ""
EndIf
For i = 1 To iCountLevels - iLevelsUp
iOutPathLen + Len(StringField(sTemp, i, #Separator)) + 1 ; + 1 für den Separator
Next i
ProcedureReturn Left(sPath, iOutPathLen)
EndProcedure
Debug PathPart("D:\Computer\Level1/Level2\Level3\", 0)
Debug PathPart("D:/Computer\Level1\Level2/Level3", 1)
Debug PathPart("D:/Computer/Level1/Level2/Level3", 2)
Vielen Dank für dein klasse Beispiel, mk-soft.
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
- NicTheQuick
- Ein Admin
- Beiträge: 8679
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
- Kontaktdaten:
Re: Smarte Methode zum Dateipfad kürzen gesucht
Für Windows gibt es auch noch eine schöne Funktion, die alle ".." und "." auflöst:
Damit könnte man notfalls auch noch arbeiten.
Code: Alles auswählen
Procedure.s canonicalizePath(path.s)
Protected newpath.s = Space(#MAX_PATH)
If PathCanonicalize_(@newpath, @path)
ProcedureReturn newpath
EndIf
ProcedureReturn ""
EndProcedure
Debug canonicalizePath("C:\Windows\system32\..\..\Program Files")
Re: Smarte Methode zum Dateipfad kürzen gesucht
@mk-soft:
Schöner Code (funktioniert allerdings nur mit absoluten Pfaden).
Er kann noch etwas vereinfacht werden.
Schöner Code (funktioniert allerdings nur mit absoluten Pfaden).
Er kann noch etwas vereinfacht werden.
Code: Alles auswählen
Procedure.s GetParentPath(Path.s, n.i=1)
Protected i.i
For i = 1 To n
Path = GetPathPart(RTrim(Path, #PS$))
Next
ProcedureReturn Path
EndProcedure
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\")
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 2)
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 3)
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 4)
Re: Smarte Methode zum Dateipfad kürzen gesucht
Dazu braucht man nur die If-Abfrage ein wenig zu ändern.Kurzer hat geschrieben:Wobei ich aber auch gemischte Path-Separatoren unterstützen wollte.
(Eine Prüfung mit If ist übrigens nicht nur hier in meiner Variante, sondern auch in mk-softs Original-Code nur 1x vor der Schleife nötig. Innerhalb der Schleife braucht man das nicht zu prüfen, weil da am Ende immer ein Pfadtrenner ist.)
Code: Alles auswählen
Procedure.s GetParentPath(Path.s, n.i=1)
Protected i.i
If FindString("\/", Right(Path, 1)) = 0
Path + #PS$
EndIf
For i = 1 To n
Path = GetPathPart(Left(Path, Len(Path)-1))
Next
ProcedureReturn Path
EndProcedure
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\")
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 2)
Debug GetParentPath("D:/Obst/Äpfel/Reife/Greenstar/", 3)
Debug GetParentPath("D:\Obst\Äpfel\Reife\Greenstar\", 4)
Re: Smarte Methode zum Dateipfad kürzen gesucht
Im CodeArchiv habe ich dafür auch ein Include: GetParentDirectory.pbi
Warum OpenSource eine Lizenz haben sollte :: PB-CodeArchiv-Rebirth :: Pleasant-Dark (Syntax-Farbschema) :: RegEx-Engine (kompiliert RegExes zu NFA/DFA)
Manjaro Xfce x64 (Hauptsystem) :: Windows 10 Home (VirtualBox) :: Neueste PureBasic-Version
Re: Smarte Methode zum Dateipfad kürzen gesucht
Gemischter Path Separator ist eigentliche nicht erforderlich.
#PS$ liefert je nach OS den richtigen Separator.
@Nino
Mist... RTrim hatte ich vergessen
#PS$ liefert je nach OS den richtigen Separator.
@Nino
Mist... RTrim hatte ich vergessen
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Re: Smarte Methode zum Dateipfad kürzen gesucht
Ja, das schon. Und unter Linux funktioniert sowieso nur "/" als Pfadtrenner.mk-soft hat geschrieben:Gemischter Path Separator ist eigentliche nicht erforderlich.
#PS$ liefert je nach OS den richtigen Separator.
Aber unter Windows kann ein Pfad auch mal den falschen Pfadtrenner "/" enthalten, oder evtl. beide gemischt: "C:\Ein/Verzeichnis". Es kommt darauf an woher der Inhalt der Variable 'Pfad' stammt. Wenn es sich z.B. um eine Benutzereingabe handelt, weiß man vorher nie was da drin ist.
mk-soft hat geschrieben:@Nino
Mist... RTrim hatte ich vergessen
Ja, dadurch wird der Code etwas kürzer. Allerdings käme es mir im Endeffekt darauf an, ob eine Variante deutlich schneller ist (habe das nicht getestet).
Re: Smarte Methode zum Dateipfad kürzen gesucht
Herzlichen Dank für eure weiteren Anregungen, Nino, Sicro und Nic.
Ich habe mich nun für diese Lösung entschieden die optional auch die Pfadseparatoren korrigert.
Code: Alles auswählen
Procedure.s GetParentPath(sPath.s, iLevelsUp.i = 1, sNewSeparator.s = "")
Protected i.i, sOldSeparator.s = ""
If FindString("\/", Right(sPath, 1)) = 0
sPath + #PS$
EndIf
For i = 1 To iLevelsUp
sPath = GetPathPart(Left(sPath, Len(sPath) - 1))
Next
Select sNewSeparator
Case "\"
sOldSeparator = "/"
ReplaceString(sPath, sOldSeparator, sNewSeparator, #PB_String_InPlace)
Case "/"
sOldSeparator = "\"
ReplaceString(sPath, sOldSeparator, sNewSeparator, #PB_String_InPlace)
EndSelect
ProcedureReturn sPath
EndProcedure
Debug GetParentPath("D:\1\Obst/Äpfel\Reife/Greenstar",2, #PS$)
Debug GetParentPath("D:/2/Obst/Äpfel/Reife/Greenstar/",2, #PS$)
Debug GetParentPath("D:\3\Obst/Äpfel\Reife/Greenstar\", 3)
Debug GetParentPath("D:\4\Obst\Äpfel\Reife\Greenstar\", 3)
Debug GetParentPath("D:\5/Obst\Äpfel\Reife\Greenstar\")
Die Hilfe sagt zu dem Parameter:
Aber offenbar gibt ReplaceString() bei Verwendung von #PB_String_InPlace statt des übergebenen Strings einen alten Stringbuffer zurück, der bei der letzten Benutzung von ReplaceString() gefüllt wurde.Wenn diese Option verwendet wird, muss das Ergebnis von ReplaceString() ignoriert werden (und auch nirgends zugewiesen - da es der als Parameter übergebene 'String$' ist, der geändert wird).
Code: Alles auswählen
Procedure.s ReturnString()
Protected sText.s
sText = "Eiscreme mit Erdbeersauce"
sText = ReplaceString(sText, "Erd", "Brom")
ProcedureReturn sText
EndProcedure
Debug ReturnString() ; Gibt 'Eiscreme mit Brombeersauce' aus
Debug ReplaceString("Hallo Welt", "Welt", "Mond", #PB_String_InPlace) ; Gibt ebenfalls 'Eiscreme mit Brombeersauce' aus!
Debug ReplaceString("Hallo Welt", "Welt", "Mond") ; Gibt 'Hallo Mond' aus
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2024: 56 Jahre.