PowerShell Как преобразовать вывод Get-ChildItem в массив строк - PullRequest
2 голосов
/ 31 октября 2019

Хорошо, работаю над этим часами и исследую как сумасшедший, но все еще не получаю что-то для работы. Мне нужен объект string[], созданный из get-childitem для передачи в параметр Copy-Item -exclude.

Препятствие в том, что мне нужно выполнить рекурсию и иметь относительные пути, так что это то, чтоЯ придумал:

$((Get-ChildItem -Path $Dest -Recurse -File).FullName.TrimStart($Dest))

Это приводит к чистому списку существующих файлов в $dest, которые представлены с относительным путем к $dest. Проблема в том, что если я добавлю это к параметру copy-item -exclude, то, похоже, его проигнорирует. Дальнейшие онлайн-исследования показывают, что copy-item будет игнорировать параметр -exclude, если он не относится к типу string[].

Если я проверю тип, возвращенный вышеуказанной командой, я получу System.Object[]. Я ожидаю, что это будет System.String[] или просто String[].

Как преобразовать вывод вышеуказанной команды в строковый массив?

ПолныйКоманда, использующая copy-item, для ясности:

Copy-Item -Path (Join-Path $src "*") -Destination $dest -Recurse -Force -Exclude $((Get-ChildItem -Path $Dest -Recurse -File).FullName.TrimStart($Dest))

Моя конечная цель - рекурсивное копирование файлов без перезаписи существующих файлов.

Ответы [ 3 ]

1 голос
/ 31 октября 2019

Чтобы получить строку [] из имен командлета get-childitem, используйте следующую команду:

[string[]]$files = (Get-ChildItem).Name
0 голосов
/ 31 октября 2019

Это будет делать то, что вы говорите, что хотите? Но я думаю, что это может быть не все на ваш вопрос.

$((Get-ChildItem -Path $Dest -Recurse -File).FullName.Replace("$Dest",'.'))
0 голосов
/ 31 октября 2019

@ mklement0 является правильным, -Exclude и -Include поддерживают шаблоны имен файлов (то есть "* .txt"), а не массив явных путей.

Это звучит ужасно, как XY Проблема ; -)

Если вы хотите просто рекурсивно копировать файлы без перезаписи, используйте Robocopy с переключателем Mirror . Например:

robocopy C:/Source C:/Dest /mir

РЕДАКТИРОВАТЬ:

По умолчанию Copy-Item всегда будет перезаписывать файлы при копировании, и нет никаких переключателей, чтобы обойти это. Я обычно рекомендую Robocopy, так как действительно упрощает подобные вещи и очень «надежен» и надежен.

Если ваши требования касаются «чистой» версии PowerShell,затем вам нужно разбить сценарий на две части: 1. получить список всех файлов 2. пройти через файлер и проверить, находятся ли они уже в месте назначения перед копированием.

$SrcPath = "C:/Source"
$DestPath = "C:/Dest"

$SrcFiles = Get-ChildItem $SrcPath -Recurse

#Iterate through files testing:
$SrcFiles | ForEach-Object {
    #Calculate Destination File/Folder name/path
    $DestObj = $_.FullName.Replace($SrcPath, $DestPath)

    if(Test-Path -LiteralPath $DestObj)
    {
        #File already Exists
        Write-Host "File already Exists: $DestObj"
    }
    else
    {
        #File Does not exist - Copy
        Write-Host "File Does not Exist Copy: $DestObj"
        Copy-Item -Path $_ -Destination $DestObj
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...