none
Probleme mit [ und ] im Pfad RRS feed

  • Frage

  • Hallo, es geht um folgendes Problem:

    Angenommen man hat ein Skript in einem Ordner, wo der Pfad so aussieht: D:\test [test]\rename.ps1

    Es geht um den Punkt, wo das Skript den Ordner nach bestimmten Dateien durchsucht.

    Das Problem ist ja im Pfad die [ und ]; denn diese sagen ja der Powershell, dass dort ein Feld dort zum Beispiel beginnt.
    Nun hat man ja mehrere Möglichkeiten: Entweder versucht den Pfad zu bearbeiten und [ oder ] durch ``[ und ``] zu ersetzen.
    Eine andere ist bei dir, gci, oder ls mit dem Schalter –literalpath zu arbeiten. Aber dieser Schalter ist aber auch wieder unschön,
    weil dann kein –include für mehrere Dateitypen geht, sondern nur –filter, was aber nur für einen Dateityp geht.

    Aber ich bekomme es nicht hin bei einem solchen Pfad nach mehreren Dateien zu filtern, wenn ich es per Rechtsklick „Mit Powershell ausführen“ starte.

    Das Skript funktioniert bei Pfaden wie D:\test\* und auch mit Dateien mit [,] (deswegen im Skript [system.io.file]::Move("$Pic","$zaehler$PicNameCut")).
    Allgemein betrifft es bei mir mehrere Skripte und bequemerweise möchte ich keinen Pfad fest in das Skript schreiben.
    Ebenso möchte ich es auch einfach in den entsprechenden Ordner kopieren und per Rechtsklick „Mit Powershell ausführen“ starten.

    das unveränderte Skript:

      $PicArray = dir ".\*" -include ('*.jpg', '*.JPG', '*.png', '*.PNG', '*.bmp', '*.BMP')
    
      $zaehler = 1
      
    # Bilder umbenennen 
      foreach($Pic in $PicArray) {
      # $PicNameCut zeigt NUR Punkt und die Datei-Endung an
        $PicNameCut = $Pic.name.substring($Pic.name.length-4, 4)
        
        [system.io.file]::Move("$Pic","$zaehler$PicNameCut")
      # rename-item "$Pic" "$zaehler$PicNameCut"  <-- funktioniert nicht bei [, ]
        $zaehler = $zaehler+1
      }

    Dienstag, 20. März 2012 13:26

Antworten

  • Grundsätzlich kann ich dir nur raten auf eckige Klammern in Pfadnamen zu verzichten. PowerShell ist nicht die einzige Anwendung die damit Probleme hat.

    Was dein aktuelles Problem betrifft:

    - damit die eckigen Klammern als solche im Pfad bleiben und in Get-childitem/dir (und ohne -Literalpath und -Filter) benutzbar sind, musst du sie in diesem Fall doppelt escapen, d.h. mit zwei Accents (``) versehen.

    - damit das Script das jeweils die Dateien in dem Verzeichnis verarbeitet, in dem es gespeichert ist, musst du das aktuelle Scriptverzeichnis auslesen. Das erhältst du mit "Split-Path -parent $MyInvocation.MyCommand.Definition".

    So geht's:

     

    $scriptpath =  Split-Path -parent $MyInvocation.MyCommand.Definition
    
    $path = $scriptpath.replace("[","``[").replace("]","``]")
    $PicArray = dir $path -include ('*.jpg', '*.JPG', '*.png', '*.PNG', '*.bmp', '*.BMP') -Recurse
    $zaehler = 1
      
    # Bilder umbenennen 
      foreach($Pic in $PicArray) {
      
        $PicNameCut = "$zaehler"+$Pic.name.substring($Pic.name.length-4, 4)
        [system.io.file]::Move($Pic.FullName,"$scriptpath\$PicNameCut")
    
        $zaehler = $zaehler+1
      }
     

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".

    Dienstag, 20. März 2012 16:44
    Moderator

Alle Antworten

  • Grundsätzlich kann ich dir nur raten auf eckige Klammern in Pfadnamen zu verzichten. PowerShell ist nicht die einzige Anwendung die damit Probleme hat.

    Was dein aktuelles Problem betrifft:

    - damit die eckigen Klammern als solche im Pfad bleiben und in Get-childitem/dir (und ohne -Literalpath und -Filter) benutzbar sind, musst du sie in diesem Fall doppelt escapen, d.h. mit zwei Accents (``) versehen.

    - damit das Script das jeweils die Dateien in dem Verzeichnis verarbeitet, in dem es gespeichert ist, musst du das aktuelle Scriptverzeichnis auslesen. Das erhältst du mit "Split-Path -parent $MyInvocation.MyCommand.Definition".

    So geht's:

     

    $scriptpath =  Split-Path -parent $MyInvocation.MyCommand.Definition
    
    $path = $scriptpath.replace("[","``[").replace("]","``]")
    $PicArray = dir $path -include ('*.jpg', '*.JPG', '*.png', '*.PNG', '*.bmp', '*.BMP') -Recurse
    $zaehler = 1
      
    # Bilder umbenennen 
      foreach($Pic in $PicArray) {
      
        $PicNameCut = "$zaehler"+$Pic.name.substring($Pic.name.length-4, 4)
        [system.io.file]::Move($Pic.FullName,"$scriptpath\$PicNameCut")
    
        $zaehler = $zaehler+1
      }
     

    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".

    Dienstag, 20. März 2012 16:44
    Moderator
  • Ich empfehle dir für die Ermittlung von Dateiendungen folgende Funktionen zu nutzen.

    über die String.substring die den letzten Punkt im String sucht und den Substring zurück gibt.
    Dies ist besser als deine Lösung die "Blind" die letzten 4 zeichen abschneidet, da auch Dateiendungen mit mehreren/weniger Zeichen  untrerstützt.
    Ebenso kann hier bei einem leeren Ergebnis erkannt werden das garkeine Dateieindung vorhanden war.
    if ($Pic.name.contains('.')) {
         $PicNameCut= $Pic.name.SubString($Pic.name.LastIndexOf('.'))
    }
    else {
        $PicNameCut= ""
    }
    Oder (besser) mit der Klasse Path:
    $PicNameCut = System.IO.Path::GetExtension($Pic.name)


    Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '



    Mittwoch, 21. März 2012 09:42
  • Stimmt. :) Und noch einfacher ist:
     

    $picnamecut = $Pic.extension

     
    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".


    Mittwoch, 21. März 2012 09:48
    Moderator
  • Danke!wieder was gelernt...

    Please click “Mark as Answer” if my post answers your question and click Vote as Help if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als Hilfreich und Beiträge die deine Frage ganz oder teilweise beantwortet haben als Antwort.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '

    Mittwoch, 21. März 2012 12:46
  • Danke für Hilfe und den Bonustipp mit der Endung. Ich hatte vorher die Skripte in vbs (hatte keine Probleme mit [,]) geschrieben und will jetzt aber primär Powershell nutzen bzw. will mal sehen, wo ich Powershell noch nutzen könnte.

    Stefan


    • Bearbeitet Golo1988 Mittwoch, 21. März 2012 15:31
    Mittwoch, 21. März 2012 15:29
  • Mir ist gerade nochmal eine Frage für mein Verständnis bzw. Arbeitsweise von PS eingefallen. Das Verzeichnis wird ja rekursiv durchsucht. Aber wenn ich nicht rekursiv durchsuchen will (also "-recurse" auskommentiere), ist die "$PicArray" wieder leer. Geht es auch ohne "-recurse"?

    Danke, Stefan

    Mittwoch, 21. März 2012 16:01
  • > Geht es auch ohne "-recurse"?
     
    Ich denke nicht. -include geht grundsätzlich nur entweder zusammen mit -recurse oder mit dem Zusatz "\*" im Pfad. In diesem speziellen Fall mit den eckigen Klammern geht Letzteres aber nicht.

     

    Ein Workaround wäre die Ergebnisse einfach nach Pfadnamen zu filtern. Beachte das dieser der Orginalpfad ($scriptpath) und nicht der "escapte' ($path) sein muß:
     

    $PicArray = dir $path  -include ('*.jpg', '*.JPG', '*.png', '*.PNG', '*.bmp', '*.BMP')  -Recurse  | Where-Object {$_.directoryname -eq $scriptpath}
     


    Grüße, Denniver


    Blog: http://bytecookie.wordpress.com

    Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".

    Mittwoch, 21. März 2012 16:29
    Moderator
  • Da habe ich heute auch wieder was gelernt. Vielen Dank.

    Stefan

    Mittwoch, 21. März 2012 18:18