我有一台 Windows Server,其中的一个文件夹中有超过 300,000 张图像。
我感觉文件系统的性能受到了影响,我想将它们移动到子文件夹中,正如许多其他人建议的那样。
我的大多数文件都是 10 个字符 + .jpg - 以 1 开头(例如:1234567890.jpg)
我想根据文件名(3 个字符一组)递归创建子文件夹 - 并将文件移动到其中。因此 1234567890.jpg 将从 c:\images 移动到 c:\Images\1\234\567\890。
我如何使用批处理文件或 wscript 来执行此操作?
答案1
PowerShell 确实是一个很好的工具。我不会为你写一个脚本,但我会为你指明正确的方向。
您可以使用列出目录中的所有内容get-childitem
,然后将其传递给foreach
循环。然后,使用.substring(0,2)
获取前三个字母。将这三个字母保存到变量中,并使用new-item -Name <foldername> -ItemType folder
替换保存前三个数字的变量来创建文件夹。测试此文件夹是否存在是个好主意,并且只有在不存在时才这样做。重复添加一些您的独特情况可能会决定的逻辑。
move-item
然后,您只需根据查看文件前三个字母的模式匹配将文件移动到文件夹中即可。
我知道你希望有人为你写一个剧本,但是授人以鱼,不如授人以渔……
答案2
PowerShell 也是我的工具;事实上,我已经想出了这个单行程序(有点像)在 c:\images 中运行:
dir *.jpg | %{ $dst = $_.basename -replace '(...)(...)(...)$','\$1\$2\$3'; md $dst >$null 2>&1; move-item $_ -Destination $dst }
扩展后的等价形式如下:
dir *.jpg
| foreach-object
{
$dst = $_.basename -replace '(...)(...)(...)$','\$1\$2\$3'
md $dst >$null 2>&1
move-item $_ -Destination $dst
}
或者,更详细一点,并在评论中举一个例子:
# if run from "c:\images\", we can get the image list
$images = dir *.jpg
# process images one by one
foreach ($image in $images)
{
# suppose $image now holds the file object for "c:\images\1234567890.jpg"
# get its file name without the extension, keeping just "1234567890"
$filenamewithoutextension = $image.basename
# group by 3 from the end, resulting in "1\234\567\890"
$destinationfolderpath =
$filenamewithoutextension -replace '(...)(...)(...)$','\$1\$2\$3'
# silently make the directory structure for "1\234\567\890"
md $destinationfolderpath >$null
# move the image from "c:\images\1234567890.jpg" to the new folder "c:\images\1\234\567\890\"
move-item $image -Destination $destinationfolderpath
# the image is now available at "c:\images\1\234\567\890\1234567890.jpg"
}
答案3
我最终使用了 wscript - 因为我还没有使用过 PowerShell。它运行速度快得惊人。我假设文件名(.ext 之前)有 10 个字符,以 1 开头
这是我运行的副本:
'On Error Resume Next
Set fso = CreateObject("Scripting.FileSystemObject")
length=10
maindir="C:\inetpub\wwwroot\InventoryImages\"
dodir "C:\inetpub\wwwroot\InventoryImages"
set files=nothing
set folder=nothing
set fso=nothing
wscript.quit
sub dodir(sFolder)
Set folder = fso.GetFolder(sFolder)
Set files = folder.Files
For each file In files
if len(file.name)=length+4 then dofile sfolder,file.name
Next
end sub
sub dofile(dir,filename)
wscript.echo dir & " - " & filename
t_filename=left(filename,10)
t_filename=mid(t_filename,2)
'ASSUMING 1 FIRST DIR
'NOT CHECKING FOR EXISTENCE
t_dir=maindir & "1\"
checkcreate t_dir & left(t_filename,3)
t_dir=t_dir & left(t_filename,3) & "\"
t_filename=mid(t_filename,4)
checkcreate t_dir & left(t_filename,3)
t_dir=t_dir & left(t_filename,3) & "\"
t_filename=mid(t_filename,4)
wscript.echo dir & "\" & filename & "->" & t_dir & filename
fso.movefile dir &"\" & filename,t_dir & filename
end sub
sub checkcreate(dir)
if not fso.FolderExists(dir) then
wscript.echo dir & " does not exist"
fso.CreateFolder(dir)
end if
end sub