Как получить сегмент пути с помощью Powershell для переименования

Я пытаюсь сделать скрипт, в котором я копирую файл из какого-то места и сохраняю его в другом. Я использую foreach рекурсивно, чтобы получить все файлы.

Возникает вопрос: как получить сегмент пути и заменить его другой строкой? Я хочу сделать что-то вроде этого:

Скопируйте файлы из

C:\sites\somefolder\folder1\file.php

to

C:\sites\anotherfolder\folder1\file.php

В этом примере мне нужно заменить «какую-то папку» на «другую папку». Вот как я получаю полный путь:

foreach ($i in Get-ChildItem -Recurse -Force) { 
   Write-host $i.Fullname
}

Внутри цикла я попытался заменить его с помощью Fullname.replace, но все пошло не так, как ожидалось:

$i.Fullname.Replace($PWD, "anotherfolder")
# This returns "anotherfolder/folder1/file.php", 
# instead of "c:\sites\anotherfolder\folder1\file.php

Я не очень разбираюсь в программировании Powershell, так что потерпите меня, хорошо?

Спасибо!


person darksoulsong    schedule 12.09.2013    source источник
comment
Для меня $PWD возвращает мой текущий рабочий каталог. Если вы не изменили $PWD только на то, что вы хотите заменить (какая-то папка), вам не повезло заставить это работать так, как вы хотите.   -  person Bruce    schedule 12.09.2013


Ответы (3)


$PWD возвращает объект PathInfo вместо строки, как вы, вероятно, ожидали. $PWD.Path возвращает строку, но даже это может быть проблематично, поскольку вы пытаетесь сопоставить весь путь. Если вы заранее знаете источник и место назначения, и они оба должны оставаться в c:\sites\, вы можете сделать что-то вроде этого:

$source = "somefolder"
$destination = "anotherfolder"

foreach ($i in Get-ChildItem -Recurse -Force) 
{ 
    $path = $i.DirectoryName -replace $source, $destination
    $name = $i.Fullname -replace $source, $destination
    if(!(Test-Path $path)) { New-Item -Path $path -ItemType directory }
    Copy-Item $i $name
}

Я сделал это немного подробным, так как вы упомянули, что вы новичок в powershell. Он заменяет исходное содержимое как для нового пути, так и для переменной имени целевым содержимым. Затем он проверяет, существует ли ваш целевой каталог, создает его, если это не так, а затем копирует элемент туда.

Когда вы меняете родительские каталоги, вы можете просто включить больше исходного пути в исходную строку, которую нужно заменить. В этом случае вы захотите использовать [regex]::Escape($Source) для экранирования специальных символов.

person Anthony Neace    schedule 12.09.2013
comment
Этот работал прекрасно. Спасибо за дополнительные пояснения, это очень помогло! - person darksoulsong; 12.09.2013

$i.Fullname.Replace($PWD, "anotherfolder")

Я думаю, что ваша проблема в переменной $PWD; попробуйте задать имя строки напрямую или проверить тип объекта $PWD.

Я попробовал то же самое на своем компьютере; он отлично работает, когда переменная $PWD содержит свойство Name:

$PWD = (gi .).Name
person plunkets    schedule 12.09.2013

foreach ($i in (Get-ChildItem -Recurse -Force)) { 
   $destination = $i.DirectoryName -Replace '\\somefolder','\anotherfolder'
   copy-item -path $i.fullname -destination $destination
}

Примечания: метод .Replace не будет работать $i.directoryname, но -replace будет работать нормально и имеет то преимущество, что является оператором регулярного выражения (следовательно, двойной \ для escape ).

person Adil Hindistan    schedule 12.09.2013