环境是Windows Server 2016.所以我有一个文件夹与290 k子文件夹.这些子文件夹需要移动.我也有一个CSV文件有两个字段,一个是(数字)文件夹名称,另一个是目标.问题:CSV包含额外的行,不仅是我需要的290 k,而且还有大约530万行。
CSV的结构基本上是:
"ORDER","CLIENT"
11223344,1111
22334455,1111
33445566,2222
44556677,1390
为了澄清,每个文件夹名称都是一个订单。订单文件夹应被分类到客户文件夹。订单是唯一的。不是每个订单都有一个文件夹。
我的第一个方法是加载CSV,然后foreach通过它。这是完全缓慢的,因为我必须检查每一个条目,如果它实际上是一个现有的文件夹。
$rootfolder = path-to-folders
$csvpath = path-to-csv
$csv = Import-csv -path $csvpath
foreach($row in $csv)
{
$path = $rootfolder + $row.ORDER
$target = $row.CLIENT
if (Test-Path -Path $path) {
# copy files to $rootfolder + $target
}
}
第二种方法是先得到子文件夹的列表,遍历它,然后从CSV中查找对应的值where-object,结果更慢。
$rootfolder = path-to-folders
$csvpath = path-to-csv
$folders = Get-ChildItem -path $rootfolder
$csv = Import-csv -path $csvpath
foreach ($folder in $folders) {
$currentpath = $rootfolder + $folder
if (Test-Path -Path $currentpath -PathType Container) {
$target = $csv | Where-Object ORDER -eq $folder
# copy files to $rootfolder + $target
}
}
我的下一个想法是将CSV加载到一个临时数据库中,并从那里进行查找,因为它应该(?)更快。
但也许有更详细的方法相比,我的穴居人的方法?感谢阅读。
2条答案
按热度按时间kqqjbcuj1#
根据评论我尝试了以下
这是更快的,它处理像300-400文件夹每秒。
感谢Jeroen Mostert指出了在处理CSV之前阅读CSV是最大的罪魁祸首和不必要的缺陷。
另一个值得一提的是,前两个“解决方案”使用了大量的资源。脚本像5.5G RAM一样拥抱。使用改进的readline()版本,它运行在30 M以下。
rur96b6h2#
这两种说法似乎相互矛盾(或者我不明白):
$target = $csv | Where-Object CLIENT -eq $folder
无论如何(以“* 澄清一下,每个文件夹名称都是一个ORDER*”为例),使用查找表可能会在性能方面产生很大的差异。要做到这一点,您可以使用此
Join-Object script
/Join-Object Module
或构建自己的查找命令,请参阅:In Powershell, what's the best way to join two tables into one?:假设您有以下(子)文件夹:
下面的Csv文件:
您可能需要执行左连接(这将显示缺失的客户端):
这意味着从这里您可以执行沿着操作: