Powershell: Obter cadeia de caracteres inicial a partir do nome do arquivo e criar diretório a partir da cadeia de caracteres e, em seguida, mover arquivos

6

Eu tenho uma pasta com os seguintes nomes de arquivo:

00150005D201110172338427995.vpf
00150005D201110180005318058.vpf
00150013D201110180014448082.vpf
00150013D201110180022268098.vpf
00150013D201110180056118137.vpf
00150004D201110180102008142.vpf
00150004D201110180105398145.vpf
00150016D201110180115378151.vpf
00150016D201110180122168161.vpf
00150003Z201110180143308169.vpf
00150050S201110180232190009.vpf

Cada arquivo começa com uma string de 9 caracteres que é um identificador exclusivo. Eu gostaria de poder pars trhouhg essas pastas para cada arquivo e com base no prefixo de 9 caracteres, criar uma pasta com o nome do prefixo e mova os arquivos para a pasta recém-criada.

Exemplo:

Antes:

f:\ION11291 Contains the following files
00150005D201110172338427995.vpf
00150005D201110180005318058.vpf
00150013D201110180014448082.vpf
00150013D201110180022268098.vpf
00150013D201110180056118137.vpf
00150004D201110180102008142.vpf
00150004D201110180105398145.vpf
00150016D201110180115378151.vpf
00150016D201110180122168161.vpf
00150003Z201110180143308169.vpf
00150050S201110180232190009.vpf

Depois:

F:\ION11291 contins only folders no files 
F:\ION11291
00150005D201110172338427995.vpf
00150005D201110180005318058.vpf
00150013D201110180014448082.vpf
00150013D201110180022268098.vpf
00150013D201110180056118137.vpf
00150004D201110180102008142.vpf
00150004D201110180105398145.vpf
00150016D201110180115378151.vpf
00150016D201110180122168161.vpf
00150003Z201110180143308169.vpf
00150050S201110180232190009.vpf
150005D contains 00150005D201110172338427995.vpf 00150005D201110180005318058.vpf F:\ION11291
f:\ION11291 Contains the following files
00150005D201110172338427995.vpf
00150005D201110180005318058.vpf
00150013D201110180014448082.vpf
00150013D201110180022268098.vpf
00150013D201110180056118137.vpf
00150004D201110180102008142.vpf
00150004D201110180105398145.vpf
00150016D201110180115378151.vpf
00150016D201110180122168161.vpf
00150003Z201110180143308169.vpf
00150050S201110180232190009.vpf
150013D\ contains 00150013D201110180014448082.vpf 00150013D201110180022268098.vpf 00150013D201110180056118137.vpf F:\ION11291
F:\ION11291 contins only folders no files 
F:\ION11291%pre%150005D contains
  00150005D201110172338427995.vpf
  00150005D201110180005318058.vpf
F:\ION11291%pre%150013D\ contains
  00150013D201110180014448082.vpf
  00150013D201110180022268098.vpf
  00150013D201110180056118137.vpf
F:\ION11291%pre%150004D \contains
  00150004D201110180102008142.vpf
  00150004D201110180105398145.vpf
F:\ION11291%pre%150016D\ contains
  00150016D201110180115378151.vpf
  00150016D201110180122168161.vpf
F:\ION11291%pre%150003Z\ contains
  00150003Z201110180143308169.vpf
F:\ION11291%pre%150050S
  00150050S201110180232190009.vpf
150004D \contains 00150004D201110180102008142.vpf 00150004D201110180105398145.vpf F:\ION11291%pre%150016D\ contains 00150016D201110180115378151.vpf 00150016D201110180122168161.vpf F:\ION11291%pre%150003Z\ contains 00150003Z201110180143308169.vpf F:\ION11291%pre%150050S 00150050S201110180232190009.vpf

Parâmetros:

  1. Eu preciso fazer isso em Powershell
  2. Eu apreciaria muito a direção de como isso poderia ser realizado, onde eu posso ler mais ou mesmo alguma orientação sobre o roteiro real.
por JRG 21.10.2011 / 07:17

2 respostas

6

Este script deve fazer o trabalho:

dir | %{ 
    $id = $_.Name.SubString(0,8); 
    if(-not (Test-Path $id)) {mkdir $id}; 
    mv $_ "$id\$_";}

Explicação:

foreach no diretório (% é um alias para foreach):

  • Obtenha o id dos 9 primeiros caracteres. Observe que a variável $ _ é uma variável automática preenchida pelo powershell que representa o arquivo atual. A propriedade Name do objeto retorna um objeto .NET String que possui uma função de membro SubString que você pode usar para retornar a parte do nome de arquivo em que está interessado.
  • Verifique se o diretório "id" já existe. Se não, crie-o (mkdir é um alias para New-Item).
  • Em seguida, mova o arquivo para o diretório (mv é um alias para Move-Item). Observe que, quando o PowerShell vê uma variável dentro de uma cadeia com aspas duplas, ela automaticamente expande seu valor para a string resultante.

Observe que o exemplo que forneço pressupõe que você o esteja executando a partir do diretório onde seus arquivos estão.

    
por 22.10.2011 / 01:14
1

Você poderia fazer algo assim:

$Directory = "f:\ION11291";
$AllFiles = Get-ChildItem $Directory | where {$_.extension -eq ".vpf"};
$FileNames = New-Object System.Collections.ArrayList;
foreach($File in $AllFiles) 
{
    $FileNames.Add($File.Name.SubString(0,9));  
}
$UniqueNames = $FileNames | get-unique;
foreach($Name in $UniqueNames)
{
    New-Item $Directory\$Name -type directory
}
foreach($File in $AllFiles)
{
    $Dir = $File.Name.SubString(0,9);        
    Move-Item $Directory\$File $Directory\$Dir\$File;
}

Explicação:

  1. Primeiro, localize todos os arquivos em $Directory com a extensão ".vdf"
  2. Adicione as primeiras 9 letras de todos os nomes de arquivos a um $FileNames
  3. Armazene cada nome exclusivo de $FileNames em $UniqueNames
  4. Crie novos diretórios com os nomes em $UniqueNames
  5. Mova cada arquivo para o diretório correspondente, com base nos primeiros 9 caracteres

Se o script sempre for executado no diretório em que os arquivos estão armazenados e você não quiser filtrar por extensão, consulte @zdans answer para obter uma solução mais compacta e elegante.

    
por 21.10.2011 / 10:44