Трубопровод в Windows PowerShell - PullRequest
0 голосов
/ 06 июня 2018

У меня есть два файла:

Файл1:

dir1
dir2
dir3

Файл2:

f1
f2
f3

Файл1 содержит список каталогов, а Файл2 содержит список файлов.Я хочу скопировать все файлы в File2, которые находятся в моем текущем каталоге, в каталоги, упомянутые в File1, используя PowerShell.Для этого я использую следующую команду:

Get-Content File2  | ForEach-Object {
    $dir = $_ ;
    Get-Content File1 |
        Copy-Item ("c:\users\")+$_ (("c:\users\")+$dir+("/")+($_))) 

Однако при этом я получаю ошибки.Может кто-нибудь, пожалуйста, помогите мне сформировать правильный запрос

Я получаю ошибку:

Входной объект не может быть привязан ни к каким параметрам для команды, потому что команда непринять вход конвейера или вход и его свойства не совпадают ни с одним из параметров, которые принимают вход конвейера.

Я хочу, чтобы f1, f2, f3 были скопированы в dir1.Снова f1, f2, f3 для копирования в dir2.И снова f1, f2, f3 для копирования в dir3.

1 Ответ

0 голосов
/ 06 июня 2018

Copy-Item имеет только один параметр, который принимает исходный путь в качестве входных данных конвейера: -Path (или -LiteralPath, в зависимости от того, какой набор параметров используется).Однако вы уже передаете исходный путь в -Path в качестве первого позиционного параметра, поэтому не осталось ни одного параметра, который мог бы принять входные данные конвейера.Вы не можете «наложить» позиционные параметры и конвейерный ввод.Это либо один, либо другой.Кроме того, $_ в операторе Copy-Item не то, что вы ожидаете.На самом деле это текущий объект из ForEach-Object, а не текущий объект из Get-Content.Вам нужно будет передать Get-Content в другой ForEach-Object и поместить Copy-Item в этот цикл, чтобы он работал так, как вы ожидаете.И, как заметил Джефф Зейтлин в комментариях , имена ваших каталогов на самом деле берутся из File1, поэтому вам нужно прочитать этот файл для внешнего цикла и File2 (с именами файлов) для внутреннего цикла.

Get-Content File1 | ForEach-Object {
    $dir = $_
    Get-Content File2 | ForEach-Object {
        Copy-Item "C:\users\${_}" "C:\users\${dir}\${_}"
    }
}

Однако в вашем сценарии это не требуется, поскольку вы можете просто добавить к выводу Get-Content File1 префикс пути и использовать его в качестве ввода для Copy-Item:

Get-Content File1 | ForEach-Object {
    $dir = $_
    (Get-Content File2) -replace '^', 'C:\users\' |
        Copy-Item -Destination {'C:\users\{0}\{1}' -f $dir, (Split-Path -Leaf $_)}
}

Обратите внимание, что для работы этого параметра вам понадобятся фигурные скобки вокруг аргумента параметра -Destination.

Примечание: По возможности избегайте конкатенации строк.PowerShell может раскрывать переменные внутри строк в двойных кавычках, что значительно улучшает читабельность.

...