Мне нравится использовать все команды Powershell, когда я могу. После небольшого тестирования это лучшее, что я могу сделать.
$source = "C:\test" $destination = "C:\test2" $filter = [regex] "^[0-9]\.(jpg|gif)" $bin = Get-ChildItem -Path $source | Where-Object {$_.Name -match $filter} foreach ($item in $bin)
Первые три строки просто для облегчения чтения, вы можете определить переменные внутри фактических команд, если хотите. Ключом к этому примеру кода является команда «Где-объект», которая является фильтром, который принимает сопоставление с регулярным выражением. Следует отметить, что поддержка регулярных выражений немного странная. Я нашел ссылку PDF карту здесь, которая имеет поддерживаемые символы на левой стороне.
[РЕДАКТИРОВАТЬ]
Как уже упоминалось "@Johannes Rössel", вы также можете уменьшить последние две строки до одной строки.
((Get-ChildItem -Path $source) -match $filter) | Copy-Item -Destination $destination
Основное отличие состоит в том, что метод Йоханнеса выполняет фильтрацию объектов, а мой - фильтрацию текста. При работе с Powershell почти всегда лучше использовать объекты.
[EDIT2]
Как упоминалось в @smoknheap, приведенные выше сценарии сгладят структуру папок и поместят все ваши файлы в одну папку. Я не уверен, есть ли переключатель, который сохраняет структуру папок. Я попробовал переключатель -Recurse, и это не помогает. Единственный способ заставить это работать - вернуться к манипуляции со строками и добавить папки в мой фильтр.
$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,"") }
Я уверен, что есть более элегантный способ сделать это, но из моих тестов это работает. Он собирает все и затем фильтрует как совпадения имен, так и объекты папок. Мне пришлось использовать метод ToString (), чтобы получить доступ к манипуляции со строками.
[EDIT3]
Теперь, если вы хотите сообщить путь, убедитесь, что у вас все правильно. Вы можете использовать команду «Write-Host». Вот код, который даст вам несколько советов о том, что происходит.
cls $source = "C:\test" $destination = "C:\test2" $filter = [regex] "^[0-9]\.(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,"") }
Это должно вернуть соответствующие строки. Если вы где-нибудь ничего не получите, вы будете знать, с какими предметами возникают проблемы.
Надеюсь это поможет