2017-06-14 28 views
1

文件夹我在文件中写了下面的脚本来批量处理文件夹根据该杂志(第一个连字符前的所有内容)的标题:移动文件与PowerShell和正则表达式

magazine title - year-month.pdfNational Geographic - 2017-07.pdf

在运行脚本后,杂志将从父文件夹移动到新的子文件夹,在本例中为“国家地理杂志”。

三个相关的问题:

  1. 的“_Orphans”文件夹(线38),即使没有“孤儿” 到文件,以供以后人工处理创建。如何使文件夹 的创建条件化?

  2. 重复文件在处理过程中会生成错误消息。脚本继续运行并不是什么大事,但我希望以与处理“孤儿”相同的方式处理重复,并带有新的“_Duplicates”文件夹/移动。

  3. 如何在每条 行(例如脚本顶部)的开头注释多行而没有#号。必须有更优雅的 方式来处理评论/文件...?

奖励题:

如果你真的很无聊等待 你看像一个沙漏进步是多TB的文件副本,任何人都可以用代码 帮助数组定界符(可能是错误的术语/名称)如第10行所示?我想 喜欢能够指定不仅仅是我在我的 正则表达式匹配中使用的硬编码连字符(第26行,这让我花了一天的更好的一部分工作)。

$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

多行注释可以用'''<#' '#>'这样''''''你的多行注释在这里#>' –

回答

0

Q1:我与遵循相同的命名方案的PDF文件进行测试我的机器上你的脚本,并没有建立一个孤儿的文件夹或移动我的孤儿PDF文件。我注意到你的foreach后立即有一个if($ _。BaseName -match $ Regex)。里面是你寻找孤儿的地方,但孤儿不会因为它们与正则表达式不匹配而进入这个区域。在伪代码,你的结构应该是这样的:

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

Q2:呵,catch块:https://blogs.technet.microsoft.com/heyscriptingguy/2014/07/05/weekend-scripter-using-try-catch-finally-blocks-for-powershell-error-handling/

Q3:您可以通过在< ##封闭加以评论多行>对。

<# 
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" 
#>