以下脚本可以运行,但速度非常慢。有人有更快的解决方案吗?
简而言之,我有一个装满恢复文件的文件夹(4M+)。我想根据扩展名为每个文件创建一个子文件夹,并将文件移动到那里。正如我所说,以下脚本非常慢。
get-childitem -file | ForEach-Object -parallel {$ext=$_.Extension; mkdir $ext; mv $_ .\$ext\} -throttlelimit 32
不管它是按照书写的方式并行运行还是不并行运行,它都很慢。
谢谢!
更新
这个问题在版本 7 中无论是否启用并行都会出现。在版本 7 中,如果不启用并行,则每个文件大约需要 15 秒。
我刚刚尝试了版本 5 中的脚本(显然没有并行),它每秒处理超过 100 个文件。
因此,这个问题现在只是理论上的问题。运行版本 5 中的脚本速度相当快,按照目前的速度,应该可以在不到 15 分钟的时间内完成 4M 以上的文件。
为什么版本 7 对于以下脚本每个文件需要 15 秒左右的时间:
get-childitem -file | ForEach-Object {$ext=$_.Extension; mkdir $ext; mv $_ .\$ext\}
答案1
尝试通过首先创建文件夹,然后使用一个命令移动每个扩展名的文件来提高速度:
$extensions = Get-Childitem | Select-Object -Unique @{label='ext';expression={$_.Extension.substring(1)}}
$extensions | foreach {New-Item -ItemType directory -Name $_.ext}
$extensions | foreach {mv "*.$($_.ext)" "$($_.ext)"}
答案2
我建议您首先创建在文件夹中找到的所有扩展名的数组(不带前导点),然后使用 robocopy 移动文件,同时创建子目录:
$sourceFolder = $PSScriptRoot # specify the path where the files are now
# get a unique array of all file extensions found in the source folder
$extensions = (Get-ChildItem -Path $sourceFolder -File | Group-Object {$_.Extension.TrimStart(".")}).Name
# loop through the extension array and have robocopy do the copying for you
foreach ($ext in $extensions) {
$targetDir = Join-Path -Path $sourceFolder -ChildPath $ext
robocopy $sourceFolder $targetDir "*.$ext" /MOV /NFL /NDL /NJH /NJS /NC /NS /NP /R:0 /W:0 > $null
}
答案3
您现有的命令可能会尝试为每个文件和扩展名创建一个目录,因此如果文件夹中有 1000 个 PDF 文档,它会运行该命令 1000 次来创建一个.pdf
子文件夹。
通过命令-Unique
的参数Select
,它仅针对每个不同或唯一的文件扩展名值运行一次该命令,以创建具有点扩展名的文件夹(例如c:\ParentFolder\.pdf
)。
我只需将所有“唯一”的文件扩展名值通过管道传输到另一个循环New-Item
,然后使用该-Force
参数即可。如果可能的话,尽量避免将另一个变量混入其中。
下一部分我将运行该Get-ChildItem
命令并将其循环到命令中Move-Item
,将具有匹配扩展名的文件移动到名为相同点扩展名的子文件夹。
Get-ChildItem -File | % { Process { $_.Extension }} | Select -Unique | % { Process { New-Item $_ -ItemType Directory -Force }};
Get-ChildItem -File | % { Process { Move-Item $_ -Destination $_.Extension -Force }};
支持资源
- ForEach 对象
标准别名对于 Foreach 对象:'
%
' 符号,ForEach - 新物品
- 移動項目