У меня Windows Server с> 300 000 изображений в одной папке.
Я чувствую, что производительность файловой системы падает, и я хотел бы переместить их в подпапки, как предлагали многие другие.
Большинство моих файлов состоят из 10 символов + .jpg - начиная с 1 (например: 1234567890.jpg)
Я хотел бы рекурсивно создавать подпапки на основе имени файла (группы из 3 символов) и перемещать в них файлы. Таким образом, 1234567890.jpg будет перемещен из c: \ images в c: \ Images \ 1 \ 234 \ 567 \ 890.
Как я могу сделать это с помощью командного файла или wscript?
PowerShell - действительно хороший инструмент для этого. Я не собираюсь писать для вас сценарий, но укажу вам правильное направление.
Вы можете перечислить все в каталоге, используя get-childitem
и они передают его foreach
петля. Затем используйте .substring(0,2)
чтобы получить первые три буквы. Сохраните эти три в переменной и создайте папку, используя new-item -Name <foldername> -ItemType folder
заменяя переменную, содержащую первые три числа. Было бы неплохо проверить наличие этой папки и делать это только в том случае, если она не существует. Повторите ополаскивание, добавляя логику, которую, вероятно, будет диктовать ваша уникальная ситуация.
Затем вы можете просто использовать move-item
для перемещения файлов в папки на основе сопоставления с образцом, учитывающим первые три буквы файла.
Я знаю, ты хотел, чтобы кто-то написал для тебя сценарий, но дай человеку рыбу, научи человека ловить рыбу ...
PowerShell также был бы моим инструментом; на самом деле, я придумал этот однострочный (вроде) для запуска в c: \ images:
dir *.jpg | %{ $dst = $_.basename -replace '(...)(...)(...)$','\$1\$2\$3'; md $dst >$null 2>&1; move-item $_ -Destination $dst }
Запланируйте себе немного PowerShell время, игрушки в ISE и учиться.
Расширенный эквивалент выглядит примерно так:
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"
}
На самом деле я закончил тем, что использовал wscript - поскольку я не играл с PowerShell. Он работал на удивление быстро. Я предположил, что имя файла из 10 символов (до .ext) начинается с 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