Parte nome do arquivo para a pasta

0

Eu tenho tentado descobrir como fazer um comando do que pode "ver" parte de um nome de arquivo, criar uma pasta e classificar cada arquivo que tenha essa parte de um nome de arquivo nela.

Todo nome de arquivo tem os seguintes caracteres (excluindo a extensão):

3 letras, 5 dígitos, 1 letra, 1 dígito

Por exemplo: BBB12345B0

Cada letra e número no nome do arquivo pode variar, mas o nome do arquivo sempre terá a mesma composição.

O que o script deve fazer é reconhecer apenas os 5 dígitos, criar uma pasta com esses 5 dígitos e depois mover esses arquivos para essa pasta.

O que encontrei na internet:

@echo off
for /f "delims=" %%a in ('dir /b /a-d') do (

if not "%%~fa"=="%~f0" (

md "%%~na" 2>nul

if exist "%%a" move "%%~na.*" "%%~na"

)

)

Isso funciona muito bem, exceto pelo fato de que todo o nome do arquivo é usado para criar uma pasta e classificar os arquivos. Eu quero que o script faça a mesma coisa, mas usando apenas os 5 dígitos.

Eu tentei trabalhar com "tokens" neste script. Também usei alguns métodos onther mas nenhum deles trabalha corretamente. Eu também não estou tão familiarizado com esse tipo de script em lote. Alguém pode me ajudar com isso?

    
por Erik 14.02.2014 / 09:00

4 respostas

0

À frente das respostas com scripts CMD para uma mudança, aqui está uma maneira diferente, usando TCC / LE da JP Software, uma alternativa intérprete de comandos:

@echo off
for %file in ([a-z][a-z][a-z][0-9][0-9][0-9][0-9][0-9][a-z][0-9].*) do ( 
    mkdir 2>NUL "%@instr[3,5,%file%]"
    ren "%file%" "%@instr[3,5,%file%]\%file%"
)

Observe que o caractere curinga bastante longo segue sua especificação e não incluirá nomes de arquivos com padrões de dígitos de letras diferentes. Um caractere curinga menos restritivo seria [?][?][?][?][?][?][?][?][?][?].* , que corresponde a cada nome de arquivo com exatamente 10 caracteres, sem extensão. Observe também que não há necessidade de um /a:-d explícito com for , já que excluir diretórios já é o padrão.

Use a opção /n para o comando ren para exibir o que aconteceria sem mover os arquivos.

É loucura analisar a saída de dir /b com for , a propósito. Mesmo no CMD da Microsoft, for pesquisa curingas em si.

Leitura adicional

  • PARA . Referência do comando TCC / LE. Software JP.
  • @INSTR . Referência do comando TCC / LE. Software JP.
por 14.02.2014 / 20:55
0

Olá, JdeBP e Martin,

Eu tentei ambas as soluções fornecidas pelo JdeBP, mas recebi um erro "arquivo não esperado". A opção de powershell por Martin parece uma boa opção. Vou procurar mais se esse tipo de script em lote, se eu tiver que usá-lo mais

    
por 17.02.2014 / 15:35
0

No PowerShell:

$files = gci . | where {!$_.psIsContainer}
foreach ($file in $files) {
    $dir = $file.Name.Substring(3, 5)
    if (!(test-path -path $dir)) {
        mkdir $dir
    }
    mv $file $dir
}

Supondo que seus arquivos estejam no diretório atual.

    
por 17.02.2014 / 17:57
0

Se for possível, você deve alternar para o PowerShell, ele pode ser instalado no WinXP e incluído por padrão no Windows Vista e, portanto, não é necessário instalar nada. Tem um monte de ferramentas que faz um monte de trabalhos que é um incômodo em lote, muito simples. E também permite que você use com-objects e a biblioteca .net em uma pitada.

Ele também permite que você use Expressões Regulares, o que torna o que você quer fazer muito mais fácil, e, além disso, você pode usar ferramentas regulares de lote, como "mkdir" se você quiser, embora seja na traseira necessário.

Existem muitos bons tutoriais se você pesquisar na web por "tutorial do powershell", etc.

(Se eu tiver tempo depois, farei um script simples que fará a tarefa que você precisa.)

Edit: Também é muito mais legível do que o lote ^^

Edit2: script curto que faz o que você precisa:

$dir="X:\Your\Path";

get-childitem $dir | %{

    $file=$_;
    if(-not $file.PSIsContainer)
    {
        if($file.PSChildName -match "^.*(\w{3})(\d{5})(\w{1})(\d{1}).*$")
        {
            $folder = "$($file.PSParentPath)\$($matches[2])";

            if(test-path $folder)
            {
                Move-Item "$($file.PSPath)" "$folder\$($file.PSChildName)";
            }
            else
            {
                mkdir $folder;
                Move-Item "$($file.PSPath)" "$folder\$($file.PSChildName)";
            }
        }
    }
}
    
por 14.02.2014 / 21:20