简体   繁体   English

Windows PowerShell中的管道

[英]Piping in windows PowerShell

I have two files: 我有两个文件:

File1: 文件1:

dir1
dir2
dir3

File2: 文件2:

f1
f2
f3

File1 contains a list of directories and File2 contains a list of files. File1包含目录列表,而File2包含文件列表。 I want to copy all files in File2 which are in my current directory into directories mentioned in File1 using PowerShell. 我想使用PowerShell将File2中当前目录中的所有文件复制到File1中提到的目录中。 For doing the same I am using the following command: 为此,我使用以下命令:

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

However, I am getting errors with this. 但是,我对此有误。 Can someone please help me form the right query 有人可以帮我形成正确的查询吗

The error which I am getting is: 我得到的错误是:

The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input. 输入对象不能绑定到该命令的任何参数,因为该命令不接受管道输入,或者该输入及其属性与接受管道输入的任何参数都不匹配。

I want f1, f2, f3 to be copied to dir1. 我希望将f1,f2,f3复制到dir1。 Again f1, f2, f3 to be copied to dir2. 再次将f1,f2,f3复制到dir2。 And again f1, f2, f3 to be copied to dir3. 再次将f1,f2,f3复制到dir3。

Copy-Item has only one parameter that accepts a source path as pipeline input: -Path (or -LiteralPath , depending on which parameter set is used). Copy-Item只有一个参数可以接受源路径作为管道输入: -Path (或-LiteralPath ,取决于使用哪个参数集)。 However, you're already passing a source path to -Path as the first positional parameter, so there's no parameter left that could accept the pipeline input. 但是,您已经将源路径传递给-Path作为第一个位置参数,因此没有剩下可以接受管道输入的参数。 You cannot "overlay" positional parameters and pipeline input. 您不能“叠加”位置参数和管道输入。 It's either one or the other. 这是一个或另一个。 Also, the $_ in the Copy-Item statement is not what you expect. 另外, Copy-Item语句中的$_不是您所期望的。 It's actually the current object from the ForEach-Object , not the current object from the Get-Content output. 它实际上是ForEach-Object的当前对象,而不是Get-Content输出中的当前对象。 You'd need to pipe Get-Content into another ForEach-Object and put Copy-Item into that loop for it to work the way you expect. 您需要将Get-Content传递到另一个ForEach-Object然后将Copy-Item放入该循环中,以使其按预期的方式工作。 And as Jeff Zeitlin pointed out in the comments, your directory names actually come from File1, so you need to read that file for the outer loop, and File2 (with the file names) for the inner loop. 正如Jeff Zeitlin在评论中指出的那样 ,您的目录名称实际上来自File1,因此您需要读取该文件作为外循环,而File2(带有文件名)作为内循环。

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

However, that's not required in your scenario, since you could simple prepend the output of Get-Content File1 with the path prefix and use that as input for Copy-Item : 但是,这在您的方案中不是必需的,因为您可以简单地在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 $_)}
}

Note that you need curly brackets around the argument of the parameter -Destination for this to work. 请注意,您需要在参数-Destination的参数周围使用大括号以使其起作用。

Side note: Avoid string concatenation wherever possible. 旁注:尽可能避免字符串串联。 PowerShell can expand variables inside double-quoted strings, which greatly improves readability. PowerShell可以在双引号字符串内扩展变量,从而大大提高了可读性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM