将文件移动到文件夹的 Powershell 脚本 - 如何从 $newFolder 中删除连字符?

Powershell script to move files to folders - how do I remove hyphens from $newFolder?

我有大量文件要根据文件名的第一部分归档到文件夹中。文件名-> 文件夹名由特定字符分隔:[-] [] [和]。示例:

第一个文件名 - 2016-04.pdf 第二个文件名和另一个名称.mp3 Third.jpg 第四个文件名,2016.pdf

我希望生成的文件夹名称不包含 [\s-] [\s] [\sand\s] 部分。

这是我的脚本,它可以运行,除了文件夹名称包含我不想要的内容,例如:

第一个文件夹名称 - 第四个文件名,

认为 这与我的正则表达式匹配贪婪地包含连字符(特别是)有关,但我不确定如何格式化查询和随后的文件夹名称创建.

此外,用“####”(如进度指示器)注释掉的内容不起作用。如果您有任何建议,请发表评论。我无论如何都不是程序员。

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

# Orphans folder, where files that return null in the regex match will be moved
# Example: file "- title.mp4"
# will be moved to ".\Sorted\_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 o 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*-)|(^\s*(.*?),)|(^\s*(.*?)\s*and\s)"

    # Loop through the $OrigFolder directory, skipping folders
Get-ChildItem -LiteralPath $OrigFolder | Where-Object {!$_.PsIsContainer} |
    ForEach-Object {
        if($_.BaseName -match $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

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

非常感谢 Whosebug 用户的帮助以及我在上面拼凑的代码片段。

以下正则表达式应该可以找到任何不需要的分隔符(使用非捕获组):

(?:\s-)|(?:,\s)|(?:\sand\s)

Here is the Demo

现在你所要做的就是使用 -replace 和那个正则表达式来摆脱它们:

if($_.BaseName -match $Regex)
{
    $ChildPath = $_.BaseName -replace $Regex

    # copy...
}

另外,看看 Write-Progress help:

If the progress bar does not appear, check the value of the $ProgressPreference variable. If the value is set to SilentlyContinue, the progress bar is not displayed. For more information about Windows PowerShell preferences, see about_Preference_Variables. The parameters of the cmdlet correspond to the properties of the ProgressRecord class (System.Management.Automation.ProgressRecord). For more information, see the ProgressRecord topic in the Windows PowerShell Software Development Kit (SDK).

这是将我的 .pdf 文件(杂志)移动到以杂志标题命名的子目录的完整脚本。感谢 jisaak (Martin Brandl) 帮助我解决正则表达式问题。将'Magazine'添加到新文件夹的解决方案在第46/47行。对大多数人来说可能是显而易见的,但我花了一个小时才弄明白。

我希望得到有关简化代码和修复缩进等的建议。我还没有 style-aware 使用 Powershell,这是我的第一次尝试

$OrigFolder = "T:\Magazines"
$NewFolder = "T:\Magazines\_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 ".\Sorted\_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 o 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 and append ' Magazine' to the 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;

我也为我的多媒体文件和图片修改了脚本,你不知道这会为我节省多少时间。再次感谢您,马丁!