Ek het 'n Windows Server met >300 000 beelde in 'n enkele vouer.

Ek voel 'n prestasie-treffer op die lêerstelsel en ek wil dit graag na subgidse skuif soos deur baie ander voorgestel is.

Die meeste van my lêers is 10 karakters + .jpg - begin met 'n 1 (bv: 1234567890.jpg)

Ek wil graag subgidse rekursief op grond van lêernaam (groepe van 3 karakters) skep - en die lêers daarin skuif. So 1234567890.jpg sal van c:\images na c:\Images\1\234\567\890 geskuif word.

Hoe kan ek dit doen met 'n bondellêer of wscript?

answer

PowerShell is regtig 'n goeie hulpmiddel hiervoor. Ek gaan nie vir jou 'n draaiboek skryf nie, maar ek sal jou in die regte rigting wys.

Jy kan alles in die gids lys deur get-childitemen hulle stuur dit na 'n foreachlus. Gebruik .substring(0,2)dan om die eerste drie letters te kry. Stoor die drie in 'n veranderlike en skep die gids deur te new-item -Name <foldername> -ItemType foldervervang met die veranderlike wat die eerste drie nommers bevat. Dit sal 'n goeie idee wees om te toets vir die bestaan ​​van hierdie lêergids en dit net te doen as dit nie bestaan ​​nie. Herhaal met skuim spoel en voeg 'n bietjie logika by wat jou unieke situasie waarskynlik sal bepaal.

Dan kan jy net gebruik move-itemom die lêers na die dopgehou te skuif op grond van patroonpassing wat na die eerste drie letters van die lêer kyk.


Ek weet jy wou hê iemand moet vir jou 'n draaiboek skryf, maar gee 'n man 'n vis, leer 'n man om vis te vang...

PowerShell sou ook my hulpmiddel wees; om die waarheid te sê, ek het met hierdie eenlyn (soort van) vorendag gekom om in c:\images te loop:

dir *.jpg | %{ $dst = $_.basename -replace '(...)(...)(...)$','\$1\$2\$3'; md $dst >$null 2>&1; move-item $_ -Destination $dst }

Beplan jouself 'n bietjie PowerShell- tyd, speel rond in die ISE en leer .


Die uitgebreide ekwivalent is iets soos hierdie:

dir *.jpg
    | foreach-object
    { 
        $dst = $_.basename -replace '(...)(...)(...)$','\$1\$2\$3'
        md $dst >$null 2>&1
        move-item $_ -Destination $dst
    }

Of, 'n bietjie meer breedvoerig en met 'n voorbeeld in opmerkings:

# 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"
}

Ek het eintlik wscript gebruik - aangesien ek nog nie met PowerShell rondgespeel het nie. Dit het verbasend vinnig gehardloop. Ek het aangeneem 10 karakter lêernaam (voor .ext) begin met 'n 1

Hier is 'n kopie van wat ek gehardloop het:

'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