lupora
Goto Top

Powershell Copy und Rename Wildcard Replacement

Hallo Experten-Team,

meine Powershell Fähigkeiten sind leider etwas schmal. Vielleicht könnt ihr weiterhelfen face-smile

Ich habe eine Excel mit folgenden nebeneinander liegenden Spalten:

Spalte A: alter Ordnername
Spalte B: Alter Dateiname
Spalte C: neuer Ordnername
Spalte D: Neuer Dateiname.

Ich suche ein Script was die Excel einliest und folgendes tut:

1. Gehe in Ordner X (Spalte A)
2. Kopiere alle Dateien die du darin findest in einen neuen Ordner (Spalte C)
3. Ändere den Dateinamen von alt (Spalte B) auf neu (Spalte D).

Soweit noch simpel und jetzt das Problem:

Die Dateien in der alten Ordnerstruktur sind so aufgebaut:

20_03_2019_Giraffe_12345_1.jpg
20_03_2019_Giraffe_12345_2.jpg usw.

Ich möchte das die Hochzählung im neuen Datei Format erhalten bleibt. Allerdings soll nur die 12345 ausgetauscht werden.
Der neue Name klingt also:

20_03_2019_Giraffe_56789_1.jpg
20_03_2019_Giraffe_56789_2.jpg


Wie stelle ich das an? :/ Bin für ein Script dankbar face-smile

mfg
Lupora

Content-ID: 542927

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

Ausgedruckt am: 22.11.2024 um 12:11 Uhr

Kraemer
Kraemer 04.02.2020 um 16:16:16 Uhr
Goto Top
Moin,

Zitat von @Lupora:
Ich möchte das die Hochzählung im neuen Datei Format erhalten bleibt. Allerdings soll nur die 12345 ausgetauscht werden.
Der neue Name klingt also:

wenn ich das richtig verstehe hast du also ein Excel-Problem, weil ja der neue Dateiname in der Spalte D steht...

Gruß
erikro
erikro 04.02.2020 um 16:45:22 Uhr
Goto Top
Moin,

Zitat von @Lupora:
Ich habe eine Excel mit folgenden nebeneinander liegenden Spalten:

Spalte A: alter Ordnername

Der vollständige Pfad?

Spalte B: Alter Dateiname

Der vollständige Dateiname oder nur "Giraffe" oder ein anderer Teilname?

Spalte C: neuer Ordnername

Auch hier: Der vollständige Pfad?

Spalte D: Neuer Dateiname.

Dieselbe Frage: Der vollständige Name oder nur 56789?

Ich suche ein Script was die Excel einliest und folgendes tut:

1. Gehe in Ordner X (Spalte A)

ok

2. Kopiere alle Dateien die du darin findest in einen neuen Ordner (Spalte C)

Auch kein Problem.

3. Ändere den Dateinamen von alt (Spalte B) auf neu (Spalte D).

Könnte man im gleichen Schritt miterledigen.

Soweit noch simpel und jetzt das Problem:

Die Dateien in der alten Ordnerstruktur sind so aufgebaut:

20_03_2019_Giraffe_12345_1.jpg
20_03_2019_Giraffe_12345_2.jpg usw.

Ich möchte das die Hochzählung im neuen Datei Format erhalten bleibt. Allerdings soll nur die 12345 ausgetauscht werden.
Der neue Name klingt also:

20_03_2019_Giraffe_56789_1.jpg
20_03_2019_Giraffe_56789_2.jpg

Auch das ist kein Problem. Aber der Aufbau ist mir noch nicht wirklich klar. Sind es immer fünf Ziffern, die im Namen geändert werden sollen? Sind es nur Ziffern oder auch Buchstaben?

Liebe Grüße

Erik
Lupora
Lupora 05.02.2020 um 08:18:53 Uhr
Goto Top
Hier ein Beispiel:

beispiel

Spalte A: Nur der Ordnername. Könnte aber auch den direkten Pfad davor packen.

Spalte B: Nur der neue Dateiname ohne das Hochzählzeichen. Siehe Bild. Also praktisch Dateiname_
Nach dem Unterstrich würde er dann die 1,2.3 usw. dran packen.

Hilft das?
Lupora
Lupora 06.02.2020 um 07:43:06 Uhr
Goto Top
Hoffe meine Antwort war verständlich face-smile
Kraemer
Kraemer 06.02.2020 um 08:47:13 Uhr
Goto Top
Zitat von @Lupora:

Hoffe meine Antwort war verständlich face-smile
bedingt. Warum fehlen in der Spalte des alten Dateinamens deine "Hochzählzeichen"?
erikro
erikro 06.02.2020 um 09:49:10 Uhr
Goto Top
Moin,

Zitat von @Lupora:

Hoffe meine Antwort war verständlich face-smile

Ja, war sie. Ich hatte gestern nur keine Zeit mehr. Erstmal zur Ausgangsdatei:
1. Speichere sie als csv.
2. Die hässlichen Leerzeichen müssen aus den Spaltennamen. Mein Skript erwartet:
altername
neuername
alterordner
neuerordner
3. In die Spalten der Ordner kommt nur der nackte Ordnername ohne Pfad.
4. In die Spalte neuername kommt nur die Zeichenfolge, die ersetzt wird ohne das, was davor oder dahinter steht.

Die Datei sieht also so aus:
alterordner	neuerordner	altername                               neuername
1234	        5678	        2019_11_25_TEST_778123436548924_	778123436548988
1234	        5678	        2019_11_25_TEST_778123436548989_	778123436548123

Und so das Skript:
param(

    [Parameter(mandatory=$true)]
    $file, # Die Übergabe der CSV-Datei
    [Parameter(mandatory=$true)]
    $oldpath, # Der Pfad zum alten Ordner
    [Parameter(mandatory=$true)]
    $newpath # Der Pfad zum neuen Ordner

)

[regex]$regex = "^(\d{4}_\d{2}_\d{2}_.+?)_.+?(_.*)$"  

$data = Import-Csv $file -Delimiter ";" -Encoding UTF8  
foreach($dataset in $data) {
 
    $files = Get-ChildItem "$oldpath\$($dataset.alterordner)\$($dataset.altername)*"  
    $new = $dataset.neuername

    if(-not (test-path $newpath\$($dataset.neuerordner))) {

        New-Item -Name $newpath\$($dataset.neuerordner) -type directory

    }

    foreach ($oldfile in $files) {

        $newfile = $oldfile.name
        $newfile = $newfile -replace $regex,"`$1_$new`$2"  
        $newfile = $newpath + "\" + $($dataset.neuerordner) + "\" + $newfile  
        move-item -path $oldfile.fullname -destination $newfile

    }
}

hth

Erik
Lupora
Lupora 06.02.2020 um 09:51:49 Uhr
Goto Top
Danke für deinen Hinweis!

Tatsächlich haben wir die Auflistung der alten Dateinamen ohne das Hochzählzeichen.
In den jeweiligen Ordnern liegen also immer rund 10 Dateien mit Hochzählung:

20_03_2019_Giraffe_12345_1.jpg
20_03_2019_Giraffe_12345_2.jpg
20_03_2019_Giraffe_12345_3.jpg
20_03_2019_Giraffe_12345_4.jpg

Ich habe aber nicht jeden Dateinamen in der Excelliste. Die Nummern sind auch unterschiedlich.
Daher war meine Idee ein Script zu haben was einfach alles im alten Ordner in den neuen Ordner (mit neuem Ordnernnamen Spalte C) kopiert.
Und dann jeweils die ID (12345) austauscht durch den Namen der in Spalte D liegt.
Es ignoriert im Prinzip ob bis 10 hochgezählt wird oder bis fünf. Es tauscht einfach die tatsächliche ID aus.
Lupora
Lupora 06.02.2020 aktualisiert um 10:27:47 Uhr
Goto Top
Herzlichen Dank für die ganze Mühe. Das sieht schon sehr gut aus!

Habe es gerade ausgeführt und folgende Fehlermeldung bekommen:
newpath: C:\Users\XXX\Desktop\YYYY\ZZZZ\ZZZ
Import-Csv : The member "7781999594424" is already present.  
At C:\Users\XXX\Desktop\shell.ps1:14 char:9
+ $data = Import-Csv $file -Delimiter ";" -Encoding UTF8  
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Import-Csv], ExtendedTypeSystemException
    + FullyQualifiedErrorId : AlreadyPresentPSMemberInfoInternalCollectionAdd,Microsoft.PowerShell.Commands.ImportCsvCommand


Vermutung: Manchmal ist der alte und der neue Ordnername identisch. Es wirkt als verschlucke er sich daran, weil er davon ausgeht das Spalte alter ordner / neuer ordner immer unterschiedlich sind.
Kann man dem SCript beibringen das zu ignorieren?
Lupora
Lupora 06.02.2020 um 10:42:50 Uhr
Goto Top
Und noch kleiner Hinweis: Könnte man es so konfigurieren das er die Ordner kopiert und nicht verschiebt?
Habe das SCript gerade mit drei Ordnern laufen lassen (test). Nach der Script Ausführung ist alles im alten Ordner weg und in den neuen sortiert.
Aus SIcherheitsgründen wäre es super, wenn es nur copy anstatt move wäre face-smile
erikro
erikro 06.02.2020 um 12:12:17 Uhr
Goto Top
Zitat von @Lupora:

Herzlichen Dank für die ganze Mühe. Das sieht schon sehr gut aus!

Habe es gerade ausgeführt und folgende Fehlermeldung bekommen:
newpath: C:\Users\XXX\Desktop\YYYY\ZZZZ\ZZZ
> Import-Csv : The member "7781999594424" is already present.  
> At C:\Users\XXX\Desktop\shell.ps1:14 char:9
> + $data = Import-Csv $file -Delimiter ";" -Encoding UTF8  
> +         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>     + CategoryInfo          : NotSpecified: (:) [Import-Csv], ExtendedTypeSystemException
>     + FullyQualifiedErrorId : AlreadyPresentPSMemberInfoInternalCollectionAdd,Microsoft.PowerShell.Commands.ImportCsvCommand


Vermutung: Manchmal ist der alte und der neue Ordnername identisch. Es wirkt als verschlucke er sich daran, weil er davon ausgeht das Spalte alter ordner / neuer ordner immer unterschiedlich sind.

Ich vermute eher, dass die Überschriften nicht stimmen. Dem Skript ist das vollkommen egal, ob der Ordner unterschiedlich oder der gleiche ist.
erikro
erikro 06.02.2020 um 12:13:29 Uhr
Goto Top
Zitat von @Lupora:

Und noch kleiner Hinweis: Könnte man es so konfigurieren das er die Ordner kopiert und nicht verschiebt?
Habe das SCript gerade mit drei Ordnern laufen lassen (test). Nach der Script Ausführung ist alles im alten Ordner weg und in den neuen sortiert.

Ja klar. Das wolltest Du doch. face-wink

Aus SIcherheitsgründen wäre es super, wenn es nur copy anstatt move wäre face-smile

Dann statt move-item einfach copy-item.
Lupora
Lupora 07.02.2020 um 09:45:22 Uhr
Goto Top
Herzlichen Dank erneut, copy-item funktioniert bestens.

Das Script läuft mittlerweile ohne Fehlermeldung durch.
Es scheint noch ein Problem beim Sortieren zu gehen.
Habe ich einen Fehler gemacht?

Testaufbau Ordnerstruktur:

  • Ordnername "originaleBilder"
  • -- Unterordner "0204113692"
2020-02-07_09h27_18

*- Unterordner "0986487611"
2020-02-07_09h27_36

CSV Datei:
0204113692;ordnerNeu1;2019_10_11_TEST_0204113692_;neuernameabc1
0986487611;ordnerNeu2;2019_10_11_TEST_0986487611_;neuernameabc2

Nach Ausführen des Scriptes gibt es:

1. Im Ordner "umsortierteBilder" zwei Unterordner mit den alten Namen der Ordner
2. In den Ordnern gibt es jeweils einen Unterordner mit identischem Namen
3. Alle Ordner sind leer:
2020-02-07_09h43_45

Was mache ich falsch? :/
erikro
erikro 07.02.2020 um 11:20:23 Uhr
Goto Top
Moin,

poste mal Dein komplettes angepasstes Skript. Und wo sind die Überschriften in der CSV?

Liebe Grüße

Erik
Lupora
Lupora 07.02.2020 um 12:47:38 Uhr
Goto Top
Ich wusste nicht das die CSV Überschriften haben muss. Dachte das war eher zu Orientierung.
Das ist das Script:

param(

    [Parameter(mandatory=$true)]
    $file, # Die Übergabe der CSV-Datei
    [Parameter(mandatory=$true)]
    $oldpath, # Der Pfad zum alten Ordner
    [Parameter(mandatory=$true)]
    $newpath # Der Pfad zum neuen Ordner

)

[regex]$regex = "^(\d{4}_\d{2}_\d{2}_.+?)_.+?(_.*)$"  

$data = Import-Csv $file -Delimiter ";" -Encoding UTF8  
foreach($dataset in $data) {
 
    $files = Get-ChildItem "$oldpath\$($dataset.alterordner)\$($dataset.altername)*"  
    $new = $dataset.neuername

    if(-not (test-path $newpath\$($dataset.neuerordner))) {

        New-Item -Name $newpath\$($dataset.neuerordner) -type directory

    }

    foreach ($oldfile in $files) {

        $newfile = $oldfile.name
        $newfile = $newfile -replace $regex,"`$1_$new`$2"  
        $newfile = $newpath + "\" + $($dataset.neuerordner) + "\" + $newfile  
        copy-item -path $oldfile.fullname -destination $newfile

    }
}
erikro
erikro 07.02.2020 um 13:07:57 Uhr
Goto Top
Moin,

Zitat von @Lupora:

Ich wusste nicht das die CSV Überschriften haben muss. Dachte das war eher zu Orientierung.

Wie schrieb ich nicht gleich:

2. Die hässlichen Leerzeichen müssen aus den Spaltennamen. Mein Skript erwartet:
altername
neuername
alterordner
neuerordner 

face-wink

Das ist das Script:

Das ist mein unverändertes Skript, wenn ich das richtig sehe? Dann klappt das, wenn die Spalten die korrekten Überschriften haben. Für's Verständnis: Der Befehl import-csv legt ein Array aus Objekten aus den Datensätzen der CSV an. Die Eigenschaften der Objekte sind die Spaltenüberschriften der CSV und die Werte dieser Eigenschaften sind die Daten selbst. So kann ich dann z. B. mit

$dataset.altername

auf den alten Dateinamen des aktuellen Objekts zugreifen. MaW: Die Überschriften sind schon wichtig und sollten deshalb auch keine Leerzeichen enthalten.

Liebe Grüße

Erik
Lupora
Lupora 07.02.2020 um 14:23:53 Uhr
Goto Top
Ich stelle mich wohl sehr ungeschickt an :/

Script erneut ausgeführt, CSV angepasst.

Fehlermeldung:
New-Item : The given path's format is not supported.  
At C:\Users\wsj8fe\Desktop\shell_clean.ps1:22 char:9
+         New-Item -Name $newpath\$($dataset.neuerordner) -type directo ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [New-Item], NotSupportedException
    + FullyQualifiedErrorId : System.NotSupportedException,Microsoft.PowerShell.Commands.NewItemCommand
 
copy-item : Could not find a part of the path 'C:\Users\umsortierteBilder\ordnerneu1\2019_10_11_TEST_204113692003_1.jpg'.  
At C:\Users\Desktop\shell_clean.ps1:31 char:9
+         copy-item -path $oldfile.fullname -destination $newfile
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Copy-Item], DirectoryNotFoundException
    + FullyQualifiedErrorId : System.IO.DirectoryNotFoundException,Microsoft.PowerShell.Commands.CopyItemCommand

neue CSV:
altername;neuername;alterordner;neuerordner
2019_10_11_TEST_0204113692_;204113692003;0204113692;ordnerneu1
2019_10_11_TEST_0986487611_;986487611003;0986487611;ordnerneu2
erikro
erikro 07.02.2020 um 16:02:30 Uhr
Goto Top
Nee, mein Fehler.

New-Item -path $newpath\$($dataset.neuerordner) -type directory

Der Parameter heißt -path und nicht -name. Das hatte ich doch vergessen zu testen. Sorry.