在PowerShell中组合文件IO-替换和设置内容

在PowerShell中组合文件IO-替换和设置内容,powershell,powershell-2.0,Powershell,Powershell 2.0,我有以下脚本: $allFiles = Get-ChildItem "./" -Recurse | Where { ($_.Extension -eq ".ts")} foreach($file in $allFiles) { # Find and replace the dash cased the contents of the files (Get-Content $file.PSPath) | Foreach-Object {$_ -replace "m

我有以下脚本:

$allFiles = Get-ChildItem "./" -Recurse | Where { ($_.Extension -eq ".ts")}
foreach($file in $allFiles)
{
    # Find and replace the dash cased the contents of the files
    (Get-Content $file.PSPath) | 
        Foreach-Object {$_ -replace "my-project-name", '$appNameDashCased$'} |
        Set-Content $file.PSPath    

    # Find and replace the dash cased the contents of the files
    (Get-Content $file.PSPath) | 
        Foreach-Object {$_ -replace "MyProjectName", '$appNameCamelCased$'} |
        Set-Content $file.PSPath    

    # Find and replace the dash cased the contents of the files
    (Get-Content $file.PSPath) | 
        Foreach-Object {$_ -replace "myProjectName", '$appNamePascalCased$'} |
        Set-Content $file.PSPath    
}
它获取一个文件并进行一些替换,然后保存该文件。然后,它接受相同的文件并进行更多替换,然后再次保存该文件。然后它再做一次

这是可行的,但似乎效率低下

是否有办法进行所有替换,然后保存一次文件?


(如果可能的话,我希望保持PowerShell的可读样式。)

当然,只需将您的替换链接到
ForEach对象
块中:

$allFiles = Get-ChildItem "./" -Recurse | Where { ($_.Extension -eq ".ts")}
foreach($file in $allFiles)
{
    (Get-Content $file.PSPath) | 
        Foreach-Object {
            # Find and replace the dash cased the contents of the files
            $_ -replace "my-project-name", '$appNameDashCased$' `
               -replace "MyProjectName", '$appNameCamelCased$' `
               -replace "myProjectName", '$appNamePascalCased$'
        } |
        Set-Content $file.PSPath    
}

这是可以做到的,实际上比你正在做的要简单得多。您可以将
-Replace
命令链接为:

$allFiles = Get-ChildItem "./" -Recurse | Where { ($_.Extension -eq ".ts")}
foreach($file in $allFiles)
{
    # Find and replace the dash cased the contents of the files
    (Get-Content $file.PSPath) -replace "my-project-name", '$appNameDashCased$' -replace "StringB", '$SecondReplacement$' -replace "StringC", '$ThirdReplacement$' | Set-Content $file.PSPath
}

美好的我认为由于管道的原因,
Set Content
可能会以这种方式失败,因此他将
Get Content
包装在括号中,以强制首先读取整个文件,但这也可以很容易地应用于此。我在PowerShell 4.0中也尝试过这种方法,但在那里也不起作用。。。。抱怨不知道替换是什么。在
获取内容
cmdlet周围添加了
()
,使其将
-replace
应用于结果,而不是尝试将其解释为
获取内容
的参数。这应该对你有用。@Xalorus我不明白。。你能进一步说明你的意思吗?我不认为有任何额外的管道需要。我删除了我的评论时,它陷入了这是一个漫长的命令。但是,您的代码没有任何东西可以使该行保持在“-replace”行的末尾,我不确定以下以-replace开头的行是否可以。我想您需要在前两个结尾处打勾。当我运行此命令时,
术语'-replace'不会被识别为cmdlet、函数、脚本文件或可操作程序的名称
。但是,如果我去掉除第一行以外的所有
-replace
行,那么它将无错误地运行。(它似乎不喜欢它放在一起的方式…)Powershell的更高版本已经实现了命令可以拆分为多行,只要剩下的不是完整的命令。描述它的最简单方法是使用括号。如果您有一个打开的插入式表达式,它将自动跨行,直到您关闭它。反勾号字符是一种强制换行的方法,它告诉控制台将下一行视为一个续行。@Vaccano我试图用换行符和反勾号使它更可读,但你可以像MadTechnician的答案一样将它们全部放在一行上。MadTechnician的答案得到了我的投票。当我看到您的代码时,还有其他一些事情:第一行很笨拙:
/
是Linux的“here”,所以请关闭该选项,Get ChildItem假设当前路径(和当前PS驱动器),如果您没有指定路径的话。将输出管道化到对象工作的位置,但在该命令中效率低下,因为该命令内置了过滤功能。另外,在使用where object子句时,括号周围有一个花括号。不需要括号
$allFiles=Get ChildItem-recurse-Include“*.ts”
。对于获取内容,您可以只使用$file对象<代码>获取内容$file