Lubię używać wszystkich poleceń Powershell, kiedy mogę. Po kilku testach jest to najlepsze, co mogę zrobić.
$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}
Pierwsze trzy wiersze mają na celu ułatwienie odczytu. Możesz zdefiniować zmienne w rzeczywistych poleceniach, jeśli chcesz. Kluczem do tego przykładu kodu jest polecenie „Where-Object”, które jest filtrem, który akceptuje dopasowanie wyrażeń regularnych. Należy zauważyć, że obsługa wyrażeń regularnych jest trochę dziwna. Znalazłem tutaj kartę referencyjną PDF z obsługiwanymi znakami po lewej stronie.
[EDYTOWAĆ]
Jak wspomniano „@Johannes Rössel”, możesz również zredukować ostatnie dwie linie do jednej linii.
((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination
Główną różnicą jest to, że sposób Johannesa filtruje obiekty, a mój sposób filtruje tekst. Podczas pracy z Powershell prawie zawsze lepiej jest używać obiektów.
[EDIT2]
Jak wspomniano @smoknheap, powyższe skrypty spłaszczą strukturę folderów i umieszczą wszystkie twoje pliki w jednym folderze. Nie jestem pewien, czy istnieje przełącznik, który zachowuje strukturę folderów. Wypróbowałem przełącznik -Recurse i to nie pomaga. Jedynym sposobem, w jaki udało mi się to uruchomić, jest powrót do manipulacji ciągami i dodawanie folderów do mojego filtra.
$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,"")
}
Jestem pewien, że jest to bardziej elegancki sposób, ale z moich testów to działa. Zbiera wszystko, a następnie filtry dla dopasowań nazw i obiektów folderów. Musiałem użyć metody ToString (), aby uzyskać dostęp do manipulacji ciągami.
[EDIT3]
Teraz, jeśli chcesz zgłosić ścieżkę, aby upewnić się, że wszystko jest poprawne. Możesz użyć polecenia „Write-Host”. Oto kod, który da ci kilka wskazówek, co się dzieje.
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,"")
}
Powinno to zwrócić odpowiednie ciągi. Jeśli gdzieś nic nie dostaniesz, będziesz wiedział, z którym przedmiotem masz problemy.
Mam nadzieję że to pomoże