Strings in Dateinamen und Ordnern ersetzen mit Liste
Hallo zusammen,
ich will ein Skript bauen das Strings in Dateinamen und Ordnernamen ersetzt. Input ist eine CSV.
Die CSV sieht so aus:
z.b. usw.
Das Skript soll eine Ordnerstruktur rekursiv durchsuchen und überall wo es eine Datei oder Ordner findet der im Dateinamen einen der alten Strings trägt, soll dieser durch den neuen ersetzt werden. Dies gilt für Dateien als auch Ordner.
Die bisherige Struktur schaut so aus:
Die CSV dazu wäre
Finale Umsetzung wäre:
Bisher habe ich in meinem Skript händisch die Werte eingetragen. Ich will das aber über eine Liste lösen, das ist wesentlich effizienter :/
Mein Versuch bisher:
gci $pfad -File -Directory -recurse | Rename-Item -newName { $_.Name -replace "alterSTring", "neuerString") } -verbose
Mit GET Content bekomme ich zwar die Liste und habe mit foreach object rumgespielt, aber ich häng seit fast 2h Stunden dran :/
Hilfe wäre toll
ich will ein Skript bauen das Strings in Dateinamen und Ordnernamen ersetzt. Input ist eine CSV.
Die CSV sieht so aus:
z.b.
oldstringX, newstringX
oldstringY, newstringY
Das Skript soll eine Ordnerstruktur rekursiv durchsuchen und überall wo es eine Datei oder Ordner findet der im Dateinamen einen der alten Strings trägt, soll dieser durch den neuen ersetzt werden. Dies gilt für Dateien als auch Ordner.
Die bisherige Struktur schaut so aus:
Elefant
-- Bilder_Januar_Elefant_TollesWetter01.jpg
-- Bilder_Januar_Elefant_TollesWetter02.jpg
-- Bilder_Januar_Elefant_TollesWetter03.jpg
Die CSV dazu wäre
Elefant, Affe
Tiger, Krokodil
Löwe, Schwein
Finale Umsetzung wäre:
Affe
-- Bilder_Januar_Affe_TollesWetter01.jpg
-- Bilder_Januar_Affe_TollesWetter02.jpg
-- Bilder_Januar_Affe_TollesWetter03.jpg
Bisher habe ich in meinem Skript händisch die Werte eingetragen. Ich will das aber über eine Liste lösen, das ist wesentlich effizienter :/
Mein Versuch bisher:
gci $pfad -File -Directory -recurse | Rename-Item -newName { $_.Name -replace "alterSTring", "neuerString") } -verbose
Mit GET Content bekomme ich zwar die Liste und habe mit foreach object rumgespielt, aber ich häng seit fast 2h Stunden dran :/
Hilfe wäre toll
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 621934
Url: https://administrator.de/contentid/621934
Ausgedruckt am: 24.11.2024 um 20:11 Uhr
8 Kommentare
Neuester Kommentar
Bin Leider noch Anfänger um dir in Powershell zu helfen, aber in Batch währe das so was ähnliches wie das: GIF
@echo off
chcp 1252 > Nul
SetLocal EnableDelayedExpansion
:: Informiere den ordner wo die dateien umbenannt werden sollen:
set Ordner=Mein Ordner
:: Informiere den Pfad zu deiner CSV datei:
set CSV=Meine CSV.csv
For /f "tokens=1,2 usebackq Delims=," %%a in ("Meine CSV.csv") do (
For /f "delims=" %%c in ('dir /b /s "%Ordner%" ^& echo %Ordner% ^|sort /r ^|find /i "%%a"') do (
set "Name=%%~nxc"
set "Name=!Name:%%a=%%b!"
IF not "!Name!"=="%%~nxc" ren "%%c" "!Name!"
)
)
exit
Wenn du bereit bist, deine CSV-Datei (data.csv) noch mit einer kleinen Überschrift zu versehen, geht es mit diesem PS-Skript:
Bei mir sah die CSV-Datei dann so aus:
$BasePath = "C:\users\username\Desktop\Beispiel\"
$CSV = Import-Csv ($BasePath + "data.csv")
foreach($file in (Get-ChildItem -Path $BasePath -Recurse -Filter "*.jpg")) {
foreach($row in $CSV) {
if($file.Name -match $row.search) {
Rename-Item $file.FullName -NewName ($file.Name -replace $row.search, $row.replace) -Verbose
}
}
}
Bei mir sah die CSV-Datei dann so aus:
search, replace
Elefant, Affe
Tiger, Krokodil
Löwe, Schwein
1. Ja, es wird nur der Teilsting ersetzt und nicht der gesamte Dateiname
2. Oh stimmt, habe gerade gesehen es geht auch ohne die Überschriften in der CSV-Datei. Es muss nur die eine Zeile wie folgt ersetzt werden:
Dann brauchst du die Kopfzeile in der Datei nicht mehr.
2. Oh stimmt, habe gerade gesehen es geht auch ohne die Überschriften in der CSV-Datei. Es muss nur die eine Zeile wie folgt ersetzt werden:
$CSV = Import-Csv ($BasePath + "data.csv") -Header "search", "replace"
Dann brauchst du die Kopfzeile in der Datei nicht mehr.
Moin,
Eine Dateiendung spielt letztenendes überhaupt keine Rolle, sondern dient lediglich dazu, dass der Benutzer schneller kapiert wofür eine Datei gedacht ist bzw. welchen Inhalt er erwarten kann. Eine CSV-Datei ist letzten Endes ja auch nur eine gewöhnliche Textdatei, die einem speziellen Dateiaufbau folgt.
Gruß Thomas
Zitat von @Lupora:
Meine letzte Frage: Kann man anstatt Import-CSV auch Import TXT machen? Falls ich keine CSV bekomme sondern TXT ?
nein, solange die Textdatei so aufgebaut ist, nutzt du auch für die TXT-Datei import-csv.Meine letzte Frage: Kann man anstatt Import-CSV auch Import TXT machen? Falls ich keine CSV bekomme sondern TXT ?
Eine Dateiendung spielt letztenendes überhaupt keine Rolle, sondern dient lediglich dazu, dass der Benutzer schneller kapiert wofür eine Datei gedacht ist bzw. welchen Inhalt er erwarten kann. Eine CSV-Datei ist letzten Endes ja auch nur eine gewöhnliche Textdatei, die einem speziellen Dateiaufbau folgt.
Zitat von @Lupora:
Ergänztung: Das Skript ändertn ur Dateinamen um. geht das auch zusötzlich für Ordner?
Das Skript ändert so derzeit nur jpg-Dateien. Wenn du in Zeile 10 -Filter "*.jpg" entfernst, wird alles verarbeitet - also auch Ordner.Ergänztung: Das Skript ändertn ur Dateinamen um. geht das auch zusötzlich für Ordner?
Gruß Thomas
Zitat von @TK1987:
Gruß Thomas
Zitat von @Lupora:
Ergänztung: Das Skript ändertn ur Dateinamen um. geht das auch zusötzlich für Ordner?
Das Skript ändert so derzeit nur jpg-Dateien. Wenn du in Zeile 10 -Filter "*.jpg" entfernst, wird alles verarbeitet - also auch Ordner.Ergänztung: Das Skript ändertn ur Dateinamen um. geht das auch zusötzlich für Ordner?
Gruß Thomas
Moin.
Das Skript oben fällt einem aber spätestens dann auf die Füße wenn sowohl der Ordner als auch enthaltene Dateien umbenannt werden müssen . Der Grund: Wird der Ordner vor der enthaltenen Datei umbenannt wird die PS beim nächsten Durchlauf die Datei ja nicht mehr finden da der Ordner ja umbenannt wurde. Deswegen muss man hier die Liste zusätzlich vorher noch nach der Länge des Absoluten Pfades absteigend sortieren damit die enthaltenen Datei vor dem übergeordneten Ordner umbenannt wird und nicht umgekehrt!
Das erreicht man bspw mittels Sort in er Pipeline
...... | sort {$_.Fullname.Length} -Descending | .....
Außerdem wurde dem TO nicht mitgeteilt das hier per Regular-Expressions gesucht wird. Wenn er also in seiner CSV so etwas literal ersetzen würde:
test[ab]
dann würde das Skript sowohl den String testa also auch testb ersetzen. Hier sollte man dann mittels Regex-Escape arbeiten wenn man in der CSV keine Regex-Escaping einsetzen will:
$file.Name -replace [regex]::Escape($row.search), $row.replace
Gruß primal