在Windows PowerShell中管道

时间:2018-06-06 10:24:33

标签: powershell powershell-v3.0

我有两个文件:

File1中:

dir1
dir2
dir3

文件2:

f1
f2
f3

File1包含目录列表,File2包含文件列表。我想使用PowerShell将File2中当前目录中的所有文件复制到File1中提到的目录中。为了做同样的事情,我使用以下命令:

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 :(得分:3)

Copy-Item只有一个参数接受源路径作为管道输入:-Path(或-LiteralPath,具体取决于使用的参数集)。但是,您已经将源路径作为第一个位置参数传递给-Path,因此没有可以接受管道输入的参数。你不能覆盖"位置参数和管道输入。它是一个或另一个。此外,$_语句中的Copy-Item不是您所期望的。它实际上是来自ForEach-Object的当前对象,而不是Get-Content输出中的当前对象。您需要将Get-Content传输到另一个ForEach-Object并将Copy-Item放入该循环中,以使其按预期方式工作。在注释中作为Jeff Zeitlin pointed out,您的目录名实际上来自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可以在双引号字符串中扩展变量,这极大地提高了可读性。