Powershell:以递归方式替换所有.ini文件中的字符串

时间:2018-12-13 12:54:56

标签: powershell

我一直想要一个易于使用的脚本,该脚本可以让我暂时替换多个文件中的多个字符串。到目前为止,我已经有了以下代码:

$replacements = @{
'bCompressDiffuseLocalPlayerCharacterTextures=True' = 'bCompressDiffuseLocalPlayerCharacterTextures=False'
'bCompressDiffuseLocalPlayerVehicleTextures=True'   = 'bCompressDiffuseLocalPlayerVehicleTextures=False'
'bCompressDiffuseOtherPlayerCharacterTextures=True' = 'bCompressDiffuseOtherPlayerCharacterTextures=False'
'bCompressDiffuseOtherPlayerVehicleTextures=True'   = 'bCompressDiffuseOtherPlayerVehicleTextures=False'
'bCompressNormalTextures=True'                      = 'bCompressNormalTextures=False'
'bDisablePhysXHardwareSupport=True'                 = 'bDisablePhysXHardwareSupport=False'
'bEnableMouseSmoothing=True'                        = 'bEnableMouseSmoothing=False'
'bInitializeShadersOnDemand=True'                   = 'bInitializeShadersOnDemand=False'
'MaxChannels=32'                                    = 'MaxChannels=64'
'MotionBlur=True'                                   = 'MotionBlur=False'
'm_bCalculateOnServer=True'                         = 'm_bCalculateOnServer=False'
'OneFrameThreadLag=True'                            = 'OneFrameThreadLag=False'
'PoolSize=140'                                      = 'PoolSize=1024'
'UseMinimalNVIDIADriverShaderOptimization=True'     = 'UseMinimalNVIDIADriverShaderOptimization=False'
'UseTextureFileCache=False'                         = 'UseTextureFileCache=True'
}

function Update-FileContent {

[cmdletbinding()]
param(
    [Parameter(ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true,
                Mandatory=$true,
                Position=0)]
    [Alias('PsPath')]
    $Path
)

$lines = Get-Content $Path
$lines | ForEach-Object {

    foreach($rep in $replacements.Keys)
    {
        $_ = $_ -replace $rep, $replacements[$rep]
    }

    $_
} | Set-Content $Path
}

Get-ChildItem -Recurse *.ini | Update-FileContent

它可以工作,但仅当文件位于1个目录深时。

1 个答案:

答案 0 :(得分:0)

我会做这样的事情:

$replacements = @{
    'bCompressDiffuseLocalPlayerCharacterTextures=True' = 'bCompressDiffuseLocalPlayerCharacterTextures=False'
    'bCompressDiffuseLocalPlayerVehicleTextures=True'   = 'bCompressDiffuseLocalPlayerVehicleTextures=False'
    'bCompressDiffuseOtherPlayerCharacterTextures=True' = 'bCompressDiffuseOtherPlayerCharacterTextures=False'
    'bCompressDiffuseOtherPlayerVehicleTextures=True'   = 'bCompressDiffuseOtherPlayerVehicleTextures=False'
    'bCompressNormalTextures=True'                      = 'bCompressNormalTextures=False'
    'bDisablePhysXHardwareSupport=True'                 = 'bDisablePhysXHardwareSupport=False'
    'bEnableMouseSmoothing=True'                        = 'bEnableMouseSmoothing=False'
    'bInitializeShadersOnDemand=True'                   = 'bInitializeShadersOnDemand=False'
    'MaxChannels=32'                                    = 'MaxChannels=64'
    'MotionBlur=True'                                   = 'MotionBlur=False'
    'm_bCalculateOnServer=True'                         = 'm_bCalculateOnServer=False'
    'OneFrameThreadLag=True'                            = 'OneFrameThreadLag=False'
    'PoolSize=140'                                      = 'PoolSize=1024'
    'UseMinimalNVIDIADriverShaderOptimization=True'     = 'UseMinimalNVIDIADriverShaderOptimization=False'
    'UseTextureFileCache=False'                         = 'UseTextureFileCache=True'
}

function Update-FileContent {
    [cmdletbinding()]
    param(
        [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true, Position=0)]
        [Alias('PsPath')]
        $Path
    )

    # read the ini file in as one single string
    $content = Get-Content $Path -Raw
    # copy that string so we can compare at the end of the loop if anything has changed at all
    $newContent = $content
    foreach($rep in $replacements.Keys) {
        $newContent = $newContent -replace $rep, $replacements[$rep]
    }
    # only replace the contents of the ini file if changes are made
    if ($newContent -ne $content) {
        Write-Host "Replacing content of file '$Path'"
        Set-Content $Path -Value $content
    }
}

$rootPath = '<PATH OF THE ROOTFOLDER TO RECURSE WHERE THE INI FILES ARE LOCATED>'
Get-ChildItem -Path $rootPath -Filter '*.ini' -Recurse | ForEach-Object { Update-FileContent $_.FullName }