2017-06-14 3 views
1

Ich schrieb das folgende Skript, um die Dateien in einem Ordner auf Batch-Prozess basierte auf dem Titel des Magazins (alles vor dem ersten Bindestrich):Verschieben von Dateien in Ordnern mit Powershell und RegEx

magazine title - year-month.pdf zB National Geographic - 2017-07.pdf

Nach dem Ausführen des Skripts werden die Magazine aus dem übergeordneten Ordner in einen neuen Unterordner verschoben, in diesem Fall "National Geographic Magazine".

Drei ähnliche Fragen:

  1. Der ‚_Orphans‘ Ordner (Zeile 38) erzeugt, auch wenn es keine "Waisen für eine spätere manuelle Bearbeitung, um es in Datei in. Wie mache ich den Ordner Erstellung bedingt?

  2. Doppelte Dateien erzeugen während der Verarbeitung eine Fehlermeldung. Keine große Sache, da das Skript weiterhin ausgeführt wird, aber ich würde gerne mit Duplikaten genauso verfahren, wie 'Waisen' behandelt werden, mit einem neuen Ordner "_Duplicates"/move.

  3. Wie kann ich mehrere Zeilen ohne die # am Anfang jeder Zeile kommentieren (zum Beispiel am Anfang des Skripts). Es muss eine elegantere Möglichkeit geben, Kommentare/Dokumentation zu behandeln ...?

Bonus Frage:

Wenn Sie sind wirklich langweilig für die Multi-TB Dateikopie warten Sie Fortschritte wie eine Stunde Glas anschauen, könnte jemand helfen mit dem Code für eine Reihe von Trennzeichen (falscher Begriff/Name wahrscheinlich) wie in Zeile 10 gezeigt? Ich würde mögen in der Lage sein, mehr als nur den hart-kodierten Bindestrich anzugeben, den ich in meinem regex Match verwendete (Linie 26, die mich den besseren Teil eines Tages nahm, um zu arbeiten).

$OrigFolder = ".\" 
$NewFolder = ".\_Sorted to Move" 

# Orphans folder, where files that return null in the regex match will be moved 
# Example: file "- title.pdf" 
# will be moved to ".\_Orphans" folder 

$Orphans = '_Orphans' # Use the underscore to sort the folder to the top of the window 

#### How to use an array of values for the delimiters in the regex instead of literals 
#### My proposed code, but I am missing how to use the delims in the regex match 
#### $delims = "\s-\s" ",\s"\s and\s" 

# First count the number of files in the $OrigFolder directory 
$numFiles = (Get-ChildItem -Path $OrigFolder).Count 
$i=0 

# Tell the user what will happen 
clear-host; 
Write-Host 'This script will copy ' $numFiles ' files from ' $OrigFolder ' to _Sorted to Move' 

# Ask user to confirm the copy operation 
Read-host -prompt 'Press enter to start copying the files' 

# Regex to match filenames 
$Regex = [regex]"(?:(.*?)\s-)|(?:(.*?),\s)|(?:(.*?)\sand\s)" 

# Loop through the $OrigFolder directory, skipping folders 
Get-ChildItem -LiteralPath $OrigFolder | Where-Object {!$_.PsIsContainer} | 
    ForEach-Object { 
     if($_.BaseName -match $Regex){ 
     $ChildPath = $_.BaseName -replace $Regex 

#Caluclate copy operation progress as a percentage 
[int]$percent = $i/$numFiles * 100 

# If first part of the file name is empty, move it to the '_Orphans' folder 
if(!$Matches[1]){ 
    $ChildPath = $Orphans} 
else { 
    $ChildPath = $Matches[1] 
    } 

# Generate new folder name 
$FolderName = Join-Path -Path $NewFolder -ChildPath ($ChildPath + ' Magazine') 

# Create folder if it doesn't exist 
    if(!(Test-Path -LiteralPath $FolderName -PathType Container)){ 
    $null = New-Item -Path $FolderName -ItemType Directory} 

# Log progress to the screen 
Write-Host "$($_.FullName) -> $FolderName" 

# Move the file to the folder 
Move-Item -LiteralPath $_.FullName -Destination $FolderName 

# Tell the user how much has been moved 
Write-Progress -Activity "Copying ... ($percent %)" -status $_ -PercentComplete $percent -verbose 
$i++ 
    } 
} 

Write-Host 'Total number of files in '$OrigFolder ' is ' $numFiles 
Write-Host 'Total number of files copied to '$NewFolder ' is ' $i 
Read-host -prompt "Press enter to complete..." 
clear-host; 
+0

mehrzeilige Kommentare können in '<#' '#>' '' '' '' # Ihr Multiline-Kommentar hier #> 'gewickelt werden –

Antwort

0

Q1: Getestet habe ich das Skript auf meinem Rechner mit PDFs, die das gleichen Namensschema gefolgt und es hat nicht einen Orphans-Ordner erstellen oder meinen Orphan PDFs bewegen. Ich habe bemerkt, dass du ein if ($ _. BaseName -match $ Regex) direkt nach deiner foreach hast. Darin suchen Sie nach Waisenkindern, aber Waisen würden es nicht in diesen Block schaffen, weil sie nicht mit der Regex übereinstimmen würden. In Pseudo-Code, sollten Sie Struktur so etwas wie:

foreach{ 
      if (match) 
       {$childpath $_.BaseName -replace $Regex} 
      else 
       {Childpath = $Orphans} 
      Create your folders and do your moves. 
} 

Q2: Versuchen Sie, Catch-Blöcke: https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/05/weekend-scripter-using-try-catch-finally-blocks-for-powershell-error-handling/

Q3: Sie können mehrere Zeilen kommentieren, indem sie in < # #> Paare umschließt.

<# 
How to use an array of values for the delimiters in the regex instead of literals 
My proposed code, but I am missing how to use the delims in the regex match 
$delims = "\s-\s" ",\s"\s and\s" 
#> 
Verwandte Themen