internet2107
Goto Top

Powershell: Dateien suchen, Ordner, Unterordner

Hallo und guten Morgen.

Leider habe ich noch einen Teil 2, den ich irgendwie nicht gelöste bekomme. Dank @colinardo (Uwe) wurde der Teil 1 sehr gut gelöst, dafür noch mal großen Dank.

Nun habe ich aber noch folgendes Problem.
Wie im Teil 1 bekannt, sollen aus Ordnern und Unterorder bestimmte Dateien gefiltert und entsprechend verarbeitet werden, was ja nun auch wieder klappt.
Nach der Verarbeitung sollen aber die verarbeiteten Dateien entsprechend an einem anderen Ort erstellt werden, inkl. dem Ordner/Unterordner wie an der Quelle.

Beispiel:
Vor der Verarbeitung soll in einem Quellordner, indem sich ca. 10.000 Dateien befinden, inkl. seiner Unterordner nach Dateien vom Typ x gesucht werden, diese werden dann verarbeitet (umgewandelt nach PDF). Das klappt ja auch einwandfrei.
Nur soll am Ziel auch genauso wieder die Ordnerstruktur erstellt werden, inkl. der Unterordner und dort die verarbeiteten Dateien abgelegt werden.

$DATDateien = dir "C:\Temp\test_dat\" -include *.mxa, *.dra, *.log -recurse    

Dieser "test_dat" - Ordner hat ggf. xx Unterordner, indem auch wieder eine Menge Dateien liegen und ggf. verarbeitet werden müssen, sofern sie die Bedingung (Filter) erfüllen.
Dann werden alle gefilterten Dateien in Word geöffnet, dort verarbeitet und als PDF gespeichert. Auch das klappt einwandfrei.

SOLL soll aber sein, dass alle Dateien im Zielordner auch jeweils genauso wieder in Unterordnern erstellt werden

Vielen Dank vorab.

Content-Key: 252420

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

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

Member: colinardo
colinardo Oct 19, 2014 updated at 09:13:29 (UTC)
Goto Top
Moin internet2107,
auch noch am Sonntag fleißig face-wink.

Auf deinen letzten Post bezogen könnt dies so aussehen:
(Kommentare siehe Code)
$sourceRoot = 'c:\deinPfad'  
$targetRoot = 'D:\deinzielPfad'  
dir $path -Include '*.xlsb' -Recurse | %{  
    # passende DAT Datei suchen
    $dat = dir "$sourceRoot\$($_.BaseName.Replace('_','-'))*_USED.DAT" -Recurse | select -First 1  
    # wenn eine zur xlsb-Datei passende DAT-Datei gefunden wurde
    if ($dat){
        write-host "Für folgende Datei wurde eine USED-DAT gefunden:"$_.FullName  
        
        # -----------------------------------------------------
        # Name des neuen Ordners erstellen indem der Quell-Root durch den Zielroot ersetzt wird
        $newDir = $_.DirectoryName.Replace($sourceRoot,$targetRoot)
        # Zielordnerstruktur erstellen
        new-item -ItemType Directory -Path $newDir -Force
        # File an seinen neuen Ort kopieren
        copy-item $_.FullName "$newDir\$($_.Name)" -Force  
        # -----------------------------------------------------
    }
}
Das Prinzip ist folgendes: Du ersetzt im Pfadnamen der Datei mit Replace dein Quell-Root mit deinem Zielroot, danach erstellst du diese Ordnerstruktur mit new-item und kopierst deine Datei dorthin, fertig.

Grüße Uwe
Member: internet2107
internet2107 Oct 21, 2014 updated at 13:51:01 (UTC)
Goto Top
Lieber Uwe.

Ich baue mir gerade den Code auch zu dieser Seite weiter zusammen.

Eine Frage hierzu.
Wie kann ich die folgende Dateibezeichnung per RegEx soweit beschneiden, dass aus:
T101361_2 (Test 2) (2281695) (2_3h) (19270236).mxa --> T101361_2
wird ?. Es soll also alles was nach dem Leerzeichen vor der ersten Klammer abgeschnitten werden ?
$string -replace '^\s ???????"

Danke im Voraus.
Member: colinardo
colinardo Oct 21, 2014 updated at 14:14:41 (UTC)
Goto Top
z.B. so
$string.Split(" (")
oder so
([regex]'^([^\s\(]+)').Match($string).Value
oder so
$string -replace '^([^\s\(]+).*','$1'
Grüße Uwe
Member: internet2107
internet2107 Oct 21, 2014 at 17:44:26 (UTC)
Goto Top
Danke für die Antwort oben. Ich komme meinem Ziel näher.
Jedoch muss hier in diesem Code noch irgendwo ein Fehler enthalten sein:

$path = "C:\Temp\test_dat\a"  
$path_pdf = "C:\Temp\test_dat\pdf"  
$path_ziel = "C:\Temp\test_dat\PDF_A_"  
$dateien = gci -path $path -include *.mxa, *.dra, *.log -recurse 

<#

..hier findet die Umwandlung der gefilterten Dateien über Word nach PDF statt.
..$doc.SaveAs([ref]$path_pdf, [ref]17) 

#>
$file_old = $dateien.basename
$file_new = $file_old -replace '^([^\s\(]+).*','$1'  
foreach ($folder in $file_new) 
{ 
New-Item -Type directory $path_ziel$folder -Force
$a1 = "\*.pdf"  
copy-Item $path_pdf$a1 $path_ziel$folder |  Where-Object  { $dateien -match $folder }
}

Beschreibung:
Nachdem die gefilterten Dateien über Word als PDF exportiert worden sind, (Word wird zur speziellen Formatierung benutzt), liegen alle PDF zunächst in einem "Sammel"-Ordner. Zur besseren Übersicht soll aber eine Ordnerstruktur erstellt werden. Der Ordner hat jeweils genau denselben Namen wie die ersten Buchstaben der Datei.
Das klappt auch alles soweit.

Am Ende sollen aber die PDFs in die vom Namen passenden Ordner kopiert werden. Hier kopiert er aber aktuell immer alle PDFs in alle Ordner.
Im Klartext:
Es befindet sich am Ende ein PDF im Ordner: "C:\Temp\test_dat\pdf\T101361_2 (Test 2) (2281695) (2_3h) (19270236).pdf"
Dieses PDF soll aber nur in erstellten Ordner: "T101361_2" kopiert werden.
Jedoch befinden sich dort aktuell auch Dateien vom Namen: "T101361_5 (Test 2) (2281695) (2_3h) (19270236).pdf", obwohl die Benennung T101361_5 eigentlich in den Ordner "T101361_5" müsste....

Sieht jemand den Fehler ?
Member: colinardo
colinardo Oct 21, 2014 updated at 21:38:20 (UTC)
Goto Top
$file_old = $dateien.basename
$file_new = $file_old -replace '^([^\s\(]+).*','$1' | select -unique  
foreach ($folder in $file_new) 
{ 
  New-Item -Type directory "$path_ziel\$folder" -Force  
  copy-Item "$path_pdf\$folder*.pdf" "$path_ziel\$folder"  
}

p.s. das angehängte where-object in deiner Zeile 18 ist ein ganz grober Fehler. Da hast du die Powershell und die Pipe noch nicht ganz durchblickt. Gefiltert werden kann immer nur vor einer Aktion ! In diesem Fall geht's aber auch ohne Filter via Wildcard im copy-Befehl.