我有大量文件要根据文件名的第一部分在文件夹中存档。文件名 - >文件夹名称由特定字符分隔:[ - ] [,] [和]。例如:
First Filename - 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;
非常感谢StackOverflow用户提供的帮助以及我上面提到的代码片段。
答案 0 :(得分:1)
以下正则表达式应该找到任何不需要的分隔符(使用非捕获组):
(?:\s-)|(?:,\s)|(?:\sand\s)
现在你所要做的就是使用-replace
和正则表达式来摆脱它们:
if($_.BaseName -match $Regex)
{
$ChildPath = $_.BaseName -replace $Regex
# copy...
}
另外,请查看Write-Progress help:
如果未显示进度条,请检查该值 $ ProgressPreference变量。如果该值设置为SilentlyContinue, 进度条不显示。有关Windows的更多信息 PowerShell首选项,请参阅about_Preference_Variables。参数 cmdlet的对应于ProgressRecord类的属性 (System.Management.Automation.ProgressRecord)。欲获得更多信息, 请参阅Windows PowerShell软件中的ProgressRecord主题 开发套件(SDK)。
答案 1 :(得分:0)
以下是将我的.pdf文件(杂志)移动到以杂志标题命名的子目录的完整脚本。感谢jisaak(Martin Brandl)帮助我解决正则表达式问题。将“杂志”添加到新文件夹的解决方案是在46/47号线上。对大多数人来说可能很明显,但我花了一个小时来弄明白。
我会喜欢精简代码和修复缩进等建议。我对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;
我已经修改了我的多媒体文件和图片的脚本,你没有想到这将节省我多少时间。再次感谢,马丁!