我是Powershell的新手。我试图将数据移动到其他地方进行处理,这些数据在它可以处理的时候对文件数量有限制。我的源文件夹有数百个子文件夹,每个子文件夹最多也可能有100个子文件夹,总计高达数百万个小文件。假设文件名是导出的唯一25位输出,因此如果排除检查会加快整个过程,则无需在每次移动时检查现有文件名。
我想自动将Powershell从源路径移动(不复制)到每个20,000个文件的增量命名目标文件夹。目标输出文件夹名称并不重要,只要它们在每个目标中的文件数不超过20,000个,并且不会重叠现有文件夹名称。
示例:
来源:C:\ MyFiles有100个子文件夹,每个子文件夹也有100个子文件夹。
C:\Myfiles\Folder000\Folder000A\file1.txt
C:\Myfiles\Folder000\Folder000A\file2.txt
C:\Myfiles\Folder000\Folder000A\file3.txt
C:\Myfiles\Folder000\Folder000B\file1.txt
C:\Myfiles\Folder000\Folder000B\file1.txt
C:\Myfiles\Folder001\Folder000A\file1.txt
...etc
目的地D:\ My20Kfiles
D:\My20kFiles\000001 [20,000 messages]
D:\My20kFiles\000002 [next 20,000 messages]
D:\My20kFiles\000003 [next 20,000 messages]
...etc
答案 0 :(得分:2)
列出文件,将其移至名为(counter ++ / 20000)的文件夹。
gci "c:\myfiles" -R -File | mv -Dest {"c:\My20kFiles\{0:d6}\" -f [math]::DivRem($global:counter++, 20000, [ref]$null)} -Force -WhatIf
未测试。因人而异。 mv将使用-Force创建文件夹。删除-WhatIf
以使其实际运行。
它实际上并不检查文件夹中的20k文件,或者它是否与现有文件夹名称重叠。但我猜这个原则适用。
同样未经测试,这会尝试将20k文件放入文件夹,然后转到下一个未使用的文件夹编号。
$FolderNumber = 0
$FilesRemainingForThisFolder = 0
Get-ChildItem "c:\myfiles" -Recurse -File | ForEach-Object {
if (0 -eq $FilesRemainingForThisFolder)
{
# Keep counting foldernumber until we get to a folder name that doesn't exist.
do {
$FolderNumber++
$DestinationFolder = "c:\My20kFiles\{0:d6}\" -f $FolderNumber
} while ((Test-Path $DestinationFolder))
mkdir $DestinationFolder
$FilesRemainingForThisFolder = 19999
}
else
{
Move-Item -LiteralPath $_.FullName -Destination $DestinationFolder -Force -WhatIf
$FilesRemainingForThisFolder--
}
}
自我生成的PS帮助链接来自我的代码块(如果有):
Get-ChildItem
(在模块Microsoft.PowerShell.Management
中)ForEach-Object
Test-Path
(在模块Microsoft.PowerShell.Management
中)Move-Item
(在模块Microsoft.PowerShell.Management
中)答案 1 :(得分:0)
以下脚本是可测试的,并执行以下任务:
检查目标文件夹是否为空,如果不是则退出。
将移动文件操作记录到名为log.txt的文件中以供后面的审核。
可以在测试模式下工作,提前知道会发生什么。
您可以定义源文件夹-target文件夹 - 增量值
function Move-Files {
param ($Source ,$Targert,$Increment=5 , $TestMode, $Logfile)
$currentpath=pwd
if (!$LogFile) {$Logfile= "{0}\{1}" -f $currentpath,"log.txt" }
"log file is created in $logfile"
# check that destination folder is empty and create
if(!(Test-Path -Path $Targert )){
$null=New-Item -ItemType directory -Path $Targert -Force
}
else
{
$targetFiles = get-childitem $Targert -Recurse -File
if ($targetFiles -ne $null) {"Target folder not empty, Please remove it";return}
}
$files=get-childitem $source -Recurse -File
$fileCounter=0
$folderCounter=0
$Nextfolder="00001"
"Moving {0} to {1}| Total Files: {2} | Increment:{3}" -f $Source, $Targert , $files.count,$increment |tee $Logfile
$files |foreach {
$fileCounter++
if ((($fileCounter - 1) % $increment) -eq 0)
{
$folderCounter++
$Nextfolder= "{0}\{1}" -f $targert, $folderCounter.ToString("000000")
"Creating new folder {0} at counter={1}" -f $Nextfolder,$fileCounter |tee -Append $Logfile
#create Folder
$null=New-Item -ItemType directory -Path $Nextfolder -Force
}
if ($testMode)
{
"mv {0} {1}" -f $_.FullName,$Nextfolder |tee -Append $Logfile
}
else
{
mv $_.FullName -Destination $Nextfolder -Force #-WhatIf
"mv {0} {1}" -f $_.FullName,$Nextfolder |tee -Append $Logfile
}
}
}
使用方法:
$source="i:\myfiles"
$targert="i:\My20kFiles"
$increment=5 # for a test, modify 20000
#run in test mode to know what will happen
$TestMode=$true # modify to $flase to actual moving files
Move-Files -Source $source -Targert $targert -Increment $increment -TestMode $TestMode
输出样本:(您在日志文件log.txt中找到相同的内容)
Moving i:\myfiles to i:\My20kFiles| Total Files: 42 | Increment:5
Creating new folder i:\My20kFiles\000001 at counter=1
mv I:\myfiles\1.txt i:\My20kFiles\000001
mv I:\myfiles\10.txt i:\My20kFiles\000001
mv I:\myfiles\11.txt i:\My20kFiles\000001
mv I:\myfiles\12.txt i:\My20kFiles\000001
mv I:\myfiles\13.txt i:\My20kFiles\000001
Creating new folder i:\My20kFiles\000002 at counter=6
mv I:\myfiles\14.txt i:\My20kFiles\000002
mv I:\myfiles\15.txt i:\My20kFiles\000002
mv I:\myfiles\16.txt i:\My20kFiles\000002
mv I:\myfiles\17.txt i:\My20kFiles\000002
mv I:\myfiles\18.txt i:\My20kFiles\000002
Creating new folder i:\My20kFiles\000003 at counter=11
mv I:\myfiles\19.txt i:\My20kFiles\000003
mv I:\myfiles\2.txt i:\My20kFiles\000003
.................
<强>更新强>
我修改了代码: 添加日志文件作为参数。默认路径是当前的PowerShell工作文件夹
$ Testmode最初为false,因此您移动文件。您可以传递参数$ Testmode = $ true以在测试模式下运行(不移动到文件),您可以查看描述文件移动位置的日志文件。
您可以根据需要自定义代码
答案 2 :(得分:0)
试试这个
$yourdir="C:\MyFiles"
$yourdestdir="D:\My20Kfiles"
$loop=20000
$i=$loop;
gci $yourdir -Recurse -File -Filter *.txt | %{$newdir="$yourdestdir\{0:d6}\" -f [math]::DivRem($i++, $loop, [ref]$null) ;new-item -Path $newdir -Force -ItemType Directory; Move-Item -Path $_.FullName -Dest $newdir -Force }