Movimenta recursivamente milhares de arquivos em janelas de subpastas

2

Eu tenho um Windows Server com > 300.000 imagens em uma única pasta.

Estou me sentindo um sucesso no desempenho do sistema de arquivos e gostaria de movê-los para subpastas, como tem sido sugerido por muitos outros.

A maioria dos meus arquivos tem 10 caracteres + .jpg - começando com 1 (por exemplo: 1234567890.jpg)

Gostaria de criar recursivamente subpastas com base no nome do arquivo (grupos de 3 caracteres) - e mover os arquivos para eles. Então 1234567890.jpg seria movido de c: \ images para c: \ Images \ 1 \ 234 \ 567 \ 890.

Como posso fazer isso com um arquivo em lotes ou wscript?

    
por user1389579 23.01.2013 / 20:02

3 respostas

3

O PowerShell é realmente uma boa ferramenta para isso. Eu não vou escrever um roteiro para você, mas vou te apontar na direção certa.

Você pode listar tudo no diretório usando get-childitem e passá-lo a um loop foreach . Em seguida, use .substring(0,2) para obter as primeiras três letras. Salve esses três para uma variável e crie a pasta usando new-item -Name <foldername> -ItemType folder substituindo a variável que contém os três primeiros números. Seria uma boa idéia testar a existência dessa pasta e fazer isso apenas se ela não existir. Lather enxaguar repetir adicionando alguma lógica que sua situação única provavelmente ditará.

Em seguida, você pode usar apenas move-item para mover os arquivos para as pastas com base na correspondência de padrões que analisa as três primeiras letras do arquivo.

Eu sei que você queria alguém para escrever um roteiro para você, mas dar um peixe a um homem, ensinar um homem a pescar ...

    
por 23.01.2013 / 20:13
1

O PowerShell também seria minha ferramenta; Na verdade, eu criei este one-liner (tipo de) para rodar em c: \ images:

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

Agende seu tempo de PowerShell , brinque no < href="http://technet.microsoft.com/pt-br/library/dd315244.aspx" title="Ambiente de Scripts Integrado"> ISE e aprenda .

O equivalente expandido é algo assim:

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

Ou, um pouco mais detalhado e com um exemplo nos comentários:

# 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:\images34567890.jpg"

    # get its file name without the extension, keeping just "1234567890"
    $filenamewithoutextension = $image.basename

    # group by 3 from the end, resulting in "1470"
    $destinationfolderpath = 
        $filenamewithoutextension -replace '(...)(...)(...)$','\\\'

    # silently make the directory structure for "1470"
    md $destinationfolderpath >$null

    # move the image from "c:\images34567890.jpg" to the new folder "c:\images470\"
    move-item $image -Destination $destinationfolderpath

    # the image is now available at "c:\images47034567890.jpg"
}
    
por 24.01.2013 / 00:22
0

Na verdade, acabei usando o wscript - já que não brinquei com o PowerShell. Ele correu surpreendentemente rápido. Eu assumi 10 nome de arquivo de caractere (antes .ext) começando com um 1

Aqui está uma cópia do que eu corri:

'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
    
por 24.01.2013 / 18:53