J'aime utiliser toutes les commandes Powershell quand je le peux. Après un peu de test, c'est le mieux que je puisse faire.
$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}
Les trois premières lignes sont juste pour faciliter la lecture, vous pouvez définir les variables à l'intérieur des commandes réelles si vous le souhaitez. La clé de cet exemple de code est la commande "Where-Object" qui est un filtre qui accepte la correspondance d'expressions régulières. Il convient de noter que le support des expressions régulières est un peu bizarre. J'ai trouvé une carte de référence PDF ici qui a les caractères pris en charge sur le côté gauche.
[ÉDITER]
Comme "@Johannes Rössel" l'a mentionné, vous pouvez également réduire les deux dernières lignes à une seule ligne.
((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination
La principale différence est que la manière de Johannes fait le filtrage d'objets et ma façon fait le filtrage de texte. Lorsque vous travaillez avec Powershell, il est presque toujours préférable d'utiliser des objets.
[EDIT2]
Comme @smoknheap l'a mentionné, les scripts ci-dessus vont aplatir la structure des dossiers et mettre tous vos fichiers dans un dossier. Je ne sais pas s'il existe un commutateur qui conserve la structure des dossiers. J'ai essayé le commutateur -Recurse et cela n'aide pas. La seule façon pour que cela fonctionne est de revenir à la manipulation des chaînes et d'ajouter des dossiers à mon filtre.
$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,"")
}
Je suis sûr qu'il existe une façon plus élégante de le faire, mais d'après mes tests, cela fonctionne. Il rassemble tout, puis filtre les correspondances de noms et les objets de dossier. J'ai dû utiliser la méthode ToString () pour accéder à la manipulation des chaînes.
[EDIT3]
Maintenant, si vous souhaitez signaler le cheminement pour vous assurer que tout est correct. Vous pouvez utiliser la commande "Write-Host". Voici le code qui vous donnera quelques conseils sur ce qui se passe.
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,"")
}
Cela devrait renvoyer les chaînes pertinentes. Si vous n'obtenez rien quelque part, vous saurez avec quel article vous rencontrez des problèmes.
J'espère que cela t'aides