Windows: Copiar / mover arquivos com o nome de arquivo de expressões regulares?

10

eu basicamente quero que seja executado:

C:\>xcopy [0-9]{13}\.(gif|jpg|png) s:\TargetFolder /s

eu sei que xcopy não suporta pesquisas de nomes de arquivos de expressões regulares.

não consigo descobrir como descobrir se o PowerShell tem Cmdlet para copiar arquivos; e se isso acontecer, como descobrir se ele suporta a correspondência de nomes de expressões regulares.

Alguém pode pensar em uma maneira de executar uma cópia / movimentação de arquivos recursivos com a correspondência de nome de arquivo regex?

    
por Ian Boyd 06.06.2010 / 22:50

3 respostas

4

Eu gosto de usar todos os comandos do Powershell quando posso. Depois de alguns testes, isso é o melhor que posso fazer.

$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source | Where-Object {$_.Name -match $filter} 
foreach ($item in $bin) {Copy-Item -Path $item.FullName -Destination $destination}

As primeiras três linhas são apenas para tornar isso mais fácil de ler, você pode definir as variáveis dentro dos comandos reais, se quiser. A chave para esse exemplo de código é o comando "Where-Object", que é um filtro que aceita correspondência de expressão regular. Deve-se notar que o suporte a expressões regulares é um pouco estranho. Encontrei um cartão de referência em PDF aqui que tem o caracteres suportados no lado esquerdo.

[EDITAR]

Como "@Johannes Rössel" mencionou, você também pode reduzir as últimas duas linhas para uma única linha.

((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination

A principal diferença é que a maneira de Johannes faz filtragem de objetos e minha maneira de filtrar texto. Ao trabalhar com o Powershell, é quase sempre melhor usar objetos.

[EDIT2]

Como @smoknheap mencionou, os scripts acima irão achatar a estrutura da pasta e colocar todos os seus arquivos em uma pasta. Não tenho certeza se existe um switch que retenha a estrutura da pasta. Eu tentei o interruptor -Recurse e isso não ajuda. A única maneira de fazer isso funcionar é voltar para a manipulação de strings e adicionar pastas ao meu filtro.

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    }

Tenho certeza de que há uma maneira mais elegante de fazer isso, mas dos meus testes funciona. Ele reúne tudo e depois filtra para correspondência de nomes e objetos de pasta. Eu tive que usar o método ToString () para obter acesso à manipulação de string.

[EDIT3]

Agora, se você quiser denunciar o pathing para ter certeza de que está tudo correto. Você pode usar o comando "Write-Host". Aqui está o código que lhe dará algumas dicas sobre o que está acontecendo.

cls
$source = "C:\test" 
$destination = "C:\test2" 
$filter = [regex] "^[0-9]{6}\.(jpg|gif)"

$bin = Get-ChildItem -Path $source -Recurse | Where-Object {($_.Name -match $filter) -or ($_.PSIsContainer)}
foreach ($item in $bin) {
    Write-Host "
----
Obj: $item
Path: "$item.fullname"
Destination: "$item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    Copy-Item -Path $item.FullName -Destination $item.FullName.ToString().Replace($source,$destination).Replace($item.Name,"")
    }

Isso deve retornar as strings relevantes. Se você não conseguir nada em algum lugar, você saberá com qual item está tendo problemas.

Espero que isso ajude

    
por 07.06.2010 / 20:57
2

O PowerShell é uma excelente ferramenta para essa tarefa. Você pode usar o cmdlet Copy-Item para o processo de cópia. Você pode canalizá-lo com outros cmdlets para comandos de cópia complexos, aqui é alguém que fez exatamente isso:)

Expressões regulares usam a classe .NET RegEx do namespace System.Text.RegularExpressions, há instruções rápidas nessas classes

O PowerShell também tem os operadores de correspondência e de substituição que podem ser usados ao pipelining com o item de cópia

Existem também ferramentas para ajudá-lo a criar o próprio RegEx, por ex. Amigos RegEx

    
por 06.06.2010 / 23:30
0

como uma ideia, mas precisa de algum trabalho

dir -r | ? {$ _ -match '[0-9] {13} \. (gif | jpg | png)'} | % {xcopy $ _. fullname c: \ temp}

    
por 07.06.2010 / 17:31