Me gusta usar todos los comandos de Powershell cuando puedo. Después de un poco de prueba, esto es lo mejor que puedo hacer.
$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}
Las primeras tres líneas son solo para que sea más fácil de leer, puede definir las variables dentro de los comandos reales si lo desea. La clave de este ejemplo de código es el comando "Where-Object", que es un filtro que acepta la coincidencia de expresiones regulares. Cabe señalar que el soporte de expresiones regulares es un poco extraño. Encontré una tarjeta de referencia en PDF aquí que tiene los caracteres admitidos en el lado izquierdo.
[EDITAR]
Como mencionó "@Johannes Rössel", también puede reducir las dos últimas líneas a una sola.
((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination
La principal diferencia es que la manera de Johannes hace el filtrado de objetos y mi forma de hacer el filtrado de texto. Cuando se trabaja con Powershell, casi siempre es mejor usar objetos.
[EDIT2]
Como @smoknheap mencionó, los scripts anteriores aplanarán la estructura de carpetas y colocarán todos sus archivos en una carpeta. No estoy seguro de si hay un interruptor que conserve la estructura de la carpeta. Intenté el interruptor -Recurse y no ayuda. La única forma de hacer que esto funcione es volver a la manipulación de cadenas y agregar carpetas a mi 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,"")
}
Estoy seguro de que hay una forma más elegante de hacer esto, pero desde mis pruebas funciona. Reúne todo y luego filtra tanto las coincidencias de nombres como los objetos de carpeta. Tuve que usar el método ToString () para obtener acceso a la manipulación de cadenas.
[EDITAR3]
Ahora, si desea informar la ruta para asegurarse de tener todo correcto. Puede usar el comando "Write-Host". Aquí está el código que le dará algunas pistas sobre lo que está sucediendo.
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,"")
}
Esto debería devolver las cadenas relevantes. Si no obtiene nada en alguna parte, sabrá con qué artículo está teniendo problemas.
Espero que esto ayude