PowerShell: Umbenennen / Löschen von Dateien in einem Ordner, der an verschiedenen Stellen in der Dateihierarchie angezeigt werden kann

481
loewie1984

Derzeit wird versucht, PDF-Dateien in einem bestimmten Ordner ( /root) umzubenennen, die sich direkt oder indirekt in einem purchasesOrdner befinden, der sich direkt oder indirekt im /rootOrdner befindet. Ich möchte dies mit PowerShell erreichen, komme aber nicht weiter als die Beispiele, die ich zu den zahlreichen Themen gefunden habe.

Zum Beispiel mit dieser Verzeichnisstruktur:

/root/<subfolder1>/purchases/invoice1.pdf /root/<subfolder1>/order.pdf /root/<subfolder2>/purchases/invoice2.pdf 

Es ist beabsichtigt, nur die PDF-Dateien umzubenennen oder zu löschen, die sich in den Ordnern "Einkauf" befinden. Die PDF-Dateien in einem anderen Ordner dürfen nicht berührt werden.

Die <subfolderX>Namen sind unbekannt (dh sie können alles sein, zB "a" oder "b").

Das Skript muss alle Ordner rekursiv ausführen.

Jede Anleitung, um dies zu erreichen, wäre zu schätzen.

1
Anstatt zwei "gci" -Aufrufe zu tätigen, wie die anderen Antworten nahelegen, können Sie einfach Folgendes tun: "gci C: \ Root * .pdf -Recurse | ? DirectoryName -imatch "purchase "` gibt nur PDF-Dateien zurück, die die Zeichenfolge" buy "enthalten, und zwar in ihrem Verzeichnisnamen (Pfad). SimonS vor 5 Jahren 1
Du hast recht @SimonS! Man kann `gci -Recurse \ root \ *. Pdf | verwenden ? {$ _. DirectoryName -imatch '. * \\ Einkäufe (\\. * | $)'} | % FullName` anstelle meiner Antwort, aber es ist nicht unbedingt schneller (abhängig von der genauen Dateistruktur), da die Filterfunktionen des PowerShell FileSystem Provider nicht verwendet werden (dh effiziente Unterstützung für Globbing). Youssef Abidi vor 5 Jahren 0

3 Antworten auf die Frage

2
Youssef Abidi

Kurze Antwort

Um die Namen der PDF-Dateien anzuzeigen, die direkt oder indirekt in einem direkten oder indirekten Unterverzeichnis von d:\rootnamed enthalten sind purchases, können Sie Folgendes verwenden:

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | % FullName 

Kurze Erklärung: Der Befehl sucht rekursiv alle direkten und indirekten Unterverzeichnisse von d:\rootnamed purchases, dann rekursiv alle PDF-Dateien in jedem dieser Unterverzeichnisse und gibt dann den vollständigen Pfad jeder dieser PDF-Dateien zurück.

Andere Anwendungsfälle

So entfernen Sie diese PDF-Dateien:

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | ri 

Um diese PDF-Dateien umzubenennen (z. B. indem Sie dem Basisnamen ein Präfix und ein Suffix hinzufügen):

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | % { rni $_ "pref-$($_.BaseName)-suff.pdf" } 

So entfernen Sie die purchasesVerzeichnisse mit ihrem gesamten Inhalt:

gci -Directory -Recurse d:\root\purchases | ri -Recurse 

Ausführliche Erklärung

  • gciist ein Alias ​​für Get-ChildItem .
  • gci -Directory -Recurse d:\root\purchasesgibt alle Verzeichnisse ( -Directory) zurück, deren Name purchasesdirekte oder indirekte ( -Recurse) Unterordner von ist d:\root\. Mit anderen Worten, es würde zurückkehren d:\root\purchases(falls vorhanden) sowie d:\root\b\c\purchasesund d:\root\a\purchases. Dies ist nicht sehr intuitiv und scheint in der Dokumentation nicht erklärt zu werden, aber es ist das aktuelle Verhalten (ab PowerShell 6).
  • %ist ein Alias ​​für ForEach-Object . Es führt einen Skriptblock (in geschweiften Klammern ( {}) eingeschlossen ) für jedes Objekt in der Pipeline aus.
  • gci -Recurse "$_\*.pdf"Ruft die Liste der PDF-Dateien ab, die (direkt oder indirekt) in den zuvor gefundenen purchasesVerzeichnissen enthalten sind.
  • % FullName wird nur verwendet, um den Pfad dieser PDF-Dateien anzuzeigen.
  • riist ein Alias ​​für Remove-Item . Die zuvor berechnete Liste der PDF-Dateien wird entfernt (da der -PathParameter des Remove-ItemBefehls Pipeline-Eingaben akzeptiert).
  • ri -Recurseermöglicht das Entfernen der zuvor berechneten Verzeichnisse purchasesmit ihrem Inhalt.
  • rni $_ "pref-$($_.BaseName)-suff.pdf"fügt dem Basisnamen der aktuellen Datei in der Pipeline ein Präfix ( pref-) und ein Suffix ( -suff) hinzu $_.BaseName(dh jede der PDF-Dateien, nach denen wir suchen). Der Basisname einer Datei ist der Name der Datei ohne Erweiterung und rniist ein Alias ​​für Rename-Item .

Testen dieser Lösung (online oder lokal)

Am einfachsten ist es , diese Lösung online auszuprobieren .

Andernfalls können Sie eine Beispielverzeichnisstruktur in einem testOrdner des aktuellen Arbeitsverzeichnisses mit dem folgenden Snippet erstellen ( Vorsicht : Wechseln .\testSie in einen anderen testOrdner, wenn sich im aktuellen Verzeichnis bereits ein Ordner befindet):

mkdir -ErrorAction SilentlyContinue .\test\a\purchases, .\test\a\e\, .\test\b\c\purchases\ Out-File .\test\a\purchases\invoice1.pdf Out-File .\test\a\order1.pdf Out-File .\test\a\e\order2.pdf Out-File .\test\b\c\purchases\invoice2.pdf Out-File .\test\b\c\purchases\invoice3.pdf 

Um alle Dateien in dieser Verzeichnisstruktur anzuzeigen, können Sie Folgendes verwenden:

gci -Recurse -File .\test | % FullName

Was würde so etwas zurückgeben:

D:\test\a\order1.pdf D:\test\a\e\order2.pdf D:\test\a\purchases\prefix-invoice1-suffix.pdf D:\test\b\c\purchases\prefix-invoice2-suffix.pdf D:\test\b\c\purchases\prefix-invoice3-suffix.pdf 

(Wo D:wird durch Ihr aktuelles Arbeitsverzeichnis ersetzt.)

Wenn Sie den als Antwort ( gci -Directory -Recurse .\test\purchases | % { gci -Recurse "$_\*.pdf" } | % FullName) bereitgestellten Befehl ausführen, werden die Dateien angezeigt, die entfernt oder gelöscht werden müssen:

D:\test\a\purchases\invoice1.pdf D:\test\b\c\purchases\invoice2.pdf D:\test\b\c\purchases\invoice3.pdf 

Nach dem Test aufräumen:

rm -Recurse .\test 
1
postanote

Youssef Abidi gab Ihnen eine Antwort, die auf ein einzelnes Laufwerk abzielte, aber es scheint, dass Sie den Ordnerpfad zu. \ Einkäufe sagen, ist unbekannt?

Die Regel des Forums lautet jedoch, dass Sie angeben müssen, was Sie versucht haben und welche Fehler Sie angetroffen haben, damit Sie zeigen, was Sie als Endziel haben, und lassen Sie uns nicht raten, und wie die meisten sagen würden: "Machen Sie Ihre Arbeit für Sie". Die Leute hier sind sehr hilfreich, aber wissen Sie.

All dies wird gesagt, wenn meine Annahme richtig ist. Führen Sie im Wesentlichen einen Filter für den Einkäufe-Ordner auf einem beliebigen Laufwerk auf dem Host und anschließend die PDF-Datei in diesem Ordner aus, und machen Sie es wie gewünscht.

Es ist wirklich nur ein Einzeiler-Befehl, wenn dies eine gültige Annahme ist

(Get-PSDrive).Root -like '*:\' |  % { (Get-ChildItem -Path ((Get-ChildItem -Path $_ -recurse -Filter Purchases -Directory -ErrorAction SilentlyContinue).FullName) -Filter '*.pdf' -Verbose).FullName }  # Results  C:\purchases\powershell-cheat-sheet.pdf C:\purchases\PSPunctuationWallChart_1_0_4.pdf D:\Temp\purchases\powershell-cheat-sheet.pdf D:\Temp\purchases\PSPunctuationWallChart_1_0_4.pdf 

Natürlich können Sie diesen One-Liner in etwas anderes einteilen.

0
loewie1984

Ich bin damit einverstanden, dass meine Hausaufgaben für die Gemeinschaft unerlässlich sind. Ich habe so viel mit gci und filter herausgefunden, konnte aber den Teil des doppelten gci zwischen Anführungszeichen nicht improvisieren.

Ich werde mein Bestes für meine nächste Frage tun, um einige Anstrengungen zu zeigen. Unabhängig davon haben mir beide Antworten geholfen, dieses Problem zu lösen.

Also nochmal vielen Dank!

Keine Sorge, wir haben alle etwas Ähnliches in unserer Karriere gemacht und den einen oder anderen Punkt. Stellen Sie sicher, dass Sie das eine oder das andere auswählen, da Sie die Antwort akzeptiert haben, zum Nutzen anderer, die ähnliche Fragen haben und auf diese stoßen. Passen Sie auf und glückliches Scripting auf. postanote vor 5 Jahren 0