10

я в основном хочу бежать:

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

я знаю, что xcopy не поддерживает поиск по имени в регулярном выражении.

я не могу узнать, как узнать, есть ли в PowerShell Cmdlet для копирования файлов; и если это так, как выяснить, поддерживает ли оно сопоставление имени файла с регулярным выражением.

Может кто-нибудь придумать, как выполнить рекурсивное копирование / перемещение файла с помощью сопоставления имен регулярных выражений?

3 ответа3

4

Мне нравится использовать все команды Powershell, когда я могу. После небольшого тестирования это лучшее, что я могу сделать.

$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}

Первые три строки просто для облегчения чтения, вы можете определить переменные внутри фактических команд, если хотите. Ключом к этому примеру кода является команда «Где-объект», которая является фильтром, который принимает сопоставление с регулярным выражением. Следует отметить, что поддержка регулярных выражений немного странная. Я нашел ссылку 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]{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,"")
    }

Это должно вернуть соответствующие строки. Если вы где-нибудь ничего не получите, вы будете знать, с какими предметами возникают проблемы.

Надеюсь это поможет

2

PowerShell - отличный инструмент для решения этой задачи. Вы можете использовать командлет Copy-Item для процесса копирования. Вы можете передать его с помощью других командлетов для сложных команд копирования, вот кто-то, кто сделал именно это :)

Регулярные выражения используют класс .NET RegEx из Системы.Текст.Пространство имен RegularExpressions, в этом классе есть быстрые инструкции

PowerShell также имеет операторы -match и -replace, которые можно использовать при конвейерной передаче с copy-item

Есть также инструменты, которые помогут вам создать самого RegEx, например, приятель RegEx

0

как идея, но нуждается в некоторой работе

dir -r | ?{$ _ -match '[0-9] {13}\.(gif | jpg | png)'} | % {xcopy $ _. полное имя c:\temp}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .