代码之家  ›  专栏  ›  技术社区  ›  Choppy The Lumberjack

为什么Powershell的Set Content-Value参数没有正确读取管道变量

  •  0
  • Choppy The Lumberjack  · 技术社区  · 3 年前

    $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
    

    然后我想通过这个值来设置content-value,如下所示:

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

    只有我所有的文件都有内容 $_.content 现在。我也试过了 -Value ($_.content) 但这样做也不对。

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

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

    0 回复  |  直到 3 年前
        1
  •  2
  •   Esperento57    3 年前

    你在试着用 delay-bind script block ( { ... } ) 为了动态地确定 Set-Content -Value 参数,基于每个管道输入对象。

    延迟绑定脚本块不能用于 ,因为该参数的类型是 [object[]] ( System.Object[] ) (见 Get-Help -Parameter Value Set-Content [scriptblock] -类型化参数。

    您确实需要一个类似循环的构造来调用 设置内容 -价值 ForEach-Object (其内置别名为 foreach )cmdlet。


    [object] [脚本块] 参数(及其数组变体)不能作为延迟绑定脚本块工作,因为作为脚本块传递给这些参数会绑定它 立刻,就像现在一样

    对于任何其他参数类型—假设该参数指定为接受管道输入—PowerShell将推断脚本块参数是延迟绑定脚本块并计算脚本块 ,然后脚本块必须确保其输出的类型与目标参数匹配。

        2
  •  -1
  •   Esperento57    3 年前

    你的问题在于“获取内容”$ .姓名

    但是你应该修改你的脚本如下:

    1. 使用Get childItem(norme powershell)
    2. 如果需要,可以使用FullName,然后使用recurse
    3. Use.Replace和not-Replace操作符(在这种情况下不起作用)

    -替换或使用正则表达式: detail here

    $replaces = Get-ChildItem -file | select FullName, @{n='content';e={(get-content $_.FullName).Replace('header-foo', 'header-bar')}}
    $replaces | %{set-content -Path $_.FullName -Value $_.content}
    
    推荐文章