【问题标题】:Find & Replace text from multiple specific files from sub folders dynamically using powershell使用powershell从子文件夹中动态查找和替换多个特定文件中的文本
【发布时间】:2019-08-25 13:41:17
【问题描述】:

我正在开发 azure CD 管道,我想更改以下文件夹结构中存在的多个文件的内容。

MainFolder => SubFolder1 => myFile1.txt
              SubFolder2 => myFile2.txt
              SubFolder3 => myFile3.txt

我想用powershell来实现我上面的要求,我试过下面的代码。

$filepath = 'C:\Users\ashishjain06\Desktop\MainFolder'
$mydata = Get-ChildItem $filepath -include *.txt -recurse | Select-Object fullName
$totalRecords = $mydata.Count
for($x = 0; $x -lt $totalRecords; $x++)
{
    ((Get-Content -path $mydata[$x] -Force) -replace 'oldText','newText') | Set-Content -Path $mydata[$x]
}

当我运行上面的代码时,它会给我以下输出。

Get-Content : Cannot find drive. A drive with the name '@{FullName=C' does not exist.
At line:6 char:7
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{FullName=C:String) [Get-Content], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

我是powershell新手,请帮我解决这个问题。

【问题讨论】:

    标签: powershell subdirectory azure-powershell file-access


    【解决方案1】:

    Get-ChildIItem 返回(一个数组)FileInfoObjects 并带有一堆属性,
    Select-Object 删除了除所选属性之外的所有属性,但它仍然是具有一个属性 FullName 的对象。
    $mydata | Get-Member

    一种方法是Select-Object -ExpandProperty FullName,
    另一个是以下脚本中使用的property dereference operator .

    要让脚本在任何用户上运行,请不要包含固定路径,使用$Env:USERPROFILE 或更好的是,让系统评估当前用户的桌面文件夹(可能会重新定位)。

    而不是通过索引迭代数组 $mydata,让 powershell 使用 foreach

    $filepath = Join-Path ([environment]::GetFolderPath('Desktop')) 'MainFolder'
    $files = (Get-ChildItem $filepath -Filter *.txt -Recurse).FullName
    
    foreach($file in $files){
       (Get-Content -path $file -Force) -replace 'oldText','newText' | Set-Content -Path $file
    }
    
    

    【讨论】:

    • 亲爱的 LotPings,我会试试这个,但是当我经历这个时,你是对的。我已接受 js2010 作为答案。
    【解决方案2】:

    除非你这样做,否则它仍然是一个具有属性的对象:

    select-object -expandproperty fullname
    

    【讨论】:

    • 非常感谢 js2010,它的工作就像一个魅力,LotPings 也给出了同样的建议,但你只是挑了伤神经。再次感谢您。
    【解决方案3】:

    Select-Object替换为ForEach-Object,即:

    $filepath = 'C:\Users\ashishjain06\Desktop\MainFolder'
    #$mydata = Get-ChildItem $filepath -include *.txt -recurse | Select-Object fullName
    $mydata = Get-ChildItem $filepath -include *.txt -recurse | ForEach-Object fullName
    $totalRecords = $mydata.Count
    for($x = 0; $x -lt $totalRecords; $x++)
    {
        ((Get-Content -path $mydata[$x] -Force) -replace 'oldText','newText') | Set-Content -Path $mydata[$x]
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-01
      • 2022-01-25
      • 2013-06-26
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      相关资源
      最近更新 更多