1

所以我试图获取一堆文件的内容来替换标题字符串:

$replaces = dir | select Name, @{n='content';e={(get-content $_) -replace "header-foo","header-bar"}}

然后给了我一个列表:

Name       Content
----       ----------
a.txt      header-foo blah blah
b.txt      header-foo blah blah blah
c.txt      header-foo blah

然后我想将 this 的值传递给 set-content -value,如下所示:

$replaces | set-content -Path {"alt/" + $_.Name} -Value {$_.content}

现在只有我所有的文件都有内容$_.content。我也尝试过-Value ($_.content),但这也没有做正确的事情。

只有当我使用 foreach 时它才会起作用:

$replaces | foreach { set-content -Path ("alt/" + $_.Name) -Value $_.content }

为什么会这样?为什么没有它就不能正常工作foreach

4

2 回答 2

2

您正在尝试使用延迟绑定脚本块( { ... }),以便根据每个管道输入对象动态确定 的参数Set-Content的参数。-Value

但是,延迟绑定脚本块不能与 一起使用-Value,因为该参数的类型是[object[]]( System.Object[])(请参阅Get-Help -Parameter Value Set-Content);同样的限制适用于[scriptblock]-typed 参数。

要解决此限制,您确实需要一个类似循环的构造,以便Set-Content 为每个预期的-Value参数调用一次,就像您对ForEach-Object(其内置别名是foreach)cmdlet 所做的那样。


[object][scriptblock]参数(及其数组变体)不能作为延迟绑定脚本块工作的原因是,作为脚本块传递给此类参数会立即将其绑定,因为参数类型与参数类型匹配。

对于任何其他参数类型 - 假设参数被指定为接受管道输入 - PowerShell 推断脚本块参数是延迟绑定脚本块,并按预期评估每个管道输入对象的脚本块和脚本块然后必须确保其输出的类型与目标参数匹配。

于 2020-12-27T13:09:59.143 回答
-1

你的问题是在 "get-content $ " 你必须使用 get-content $ .Name

但是你应该像这样修改你的脚本:

  1. 使用 Get-childItem (norme powershell)
  2. 使用 -file 只获取文件而不是目录
  3. 使用 FullName,然后可以在必要时使用递归
  4. 使用 .Replace 而不是 -replace 运算符(在这种情况下不起作用)

-替换使用正则表达式:这里有详细信息

$replaces = Get-ChildItem -file | select FullName, @{n='content';e={(get-content $_.FullName).Replace('header-foo', 'header-bar')}}
$replaces | %{set-content -Path $_.FullName -Value $_.content}
于 2020-12-27T12:12:07.247 回答