Comment remplacer plusieurs chaînes dans un fichier à l’aide de PowerShell

J’écris un script pour personnaliser un fichier de configuration. Je veux remplacer plusieurs instances de chaînes dans ce fichier et j’ai essayé d’utiliser PowerShell pour faire le travail.

Cela fonctionne très bien pour un remplacement simple, mais faire plusieurs remplacements est très lent car à chaque fois il doit parsingr à nouveau le fichier entier, et ce fichier est très volumineux. Le script ressemble à ceci:

$original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' (Get-Content $original_file) | Foreach-Object { $_ -replace 'something1', 'something1new' } | Set-Content $destination_file 

Je veux quelque chose comme ça, mais je ne sais pas comment l’écrire:

 $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' (Get-Content $original_file) | Foreach-Object { $_ -replace 'something1', 'something1aa' $_ -replace 'something2', 'something2bb' $_ -replace 'something3', 'something3cc' $_ -replace 'something4', 'something4dd' $_ -replace 'something5', 'something5dsf' $_ -replace 'something6', 'something6dfsfds' } | Set-Content $destination_file 

Une option consiste à enchaîner les opérations en place. Le ` à la fin de chaque ligne échappe à la nouvelle ligne, PowerShell continue à parsingr l’expression sur la ligne suivante:

 $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' (Get-Content $original_file) | Foreach-Object { $_ -replace 'something1', 'something1aa' ` -replace 'something2', 'something2bb' ` -replace 'something3', 'something3cc' ` -replace 'something4', 'something4dd' ` -replace 'something5', 'something5dsf' ` -replace 'something6', 'something6dfsfds' } | Set-Content $destination_file 

Une autre option serait d’affecter une variable intermédiaire:

 $x = $_ -replace 'something1', 'something1aa' $x = $x -replace 'something2', 'something2bb' ... $x 

Pour que l’article de George Howarth fonctionne correctement avec plus d’un remplacement, vous devez supprimer le saut, assigner la sortie à une variable ($ line), puis générer la variable:

 $lookupTable = @{ 'something1' = 'something1aa' 'something2' = 'something2bb' 'something3' = 'something3cc' 'something4' = 'something4dd' 'something5' = 'something5dsf' 'something6' = 'something6dfsfds' } $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' Get-Content -Path $original_file | ForEach-Object { $line = $_ $lookupTable.GetEnumerator() | ForEach-Object { if ($line -match $_.Key) { $line = $line -replace $_.Key, $_.Value } } $line } | Set-Content -Path $destination_file 

En supposant que vous ne pouvez avoir qu’un seul 'something1' ou 'something2' , etc. par ligne, vous pouvez utiliser une table de recherche:

 $lookupTable = @{ 'something1' = 'something1aa' 'something2' = 'something2bb' 'something3' = 'something3cc' 'something4' = 'something4dd' 'something5' = 'something5dsf' 'something6' = 'something6dfsfds' } $original_file = 'path\filename.abc' $destination_file = 'path\filename.abc.new' Get-Content -Path $original_file | ForEach-Object { $line = $_ $lookupTable.GetEnumerator() | ForEach-Object { if ($line -match $_.Key) { $line -replace $_.Key, $_.Value break } } } | Set-Content -Path $destination_file 

Si vous pouvez en avoir plus d’un, supprimez simplement le break dans l’instruction if .

Avec la version 3 de PowerShell, vous pouvez enchaîner les appels de remplacement:

  (Get-Content $sourceFile) | ForEach-Object { $_.replace('something1', 'something1').replace('somethingElse1', 'somethingElse2') } | Set-Content $destinationFile 

Une troisième option, pour un one-liner en pipeline, consiste à imbriquer les lieux:

 PS> ("ABC" -replace "B","C") -replace "C","D" ADD 

Et:

 PS> ("ABC" -replace "C","D") -replace "B","C" ACD 

Cela préserve l’ordre d’exécution, est facile à lire et s’intègre parfaitement dans un pipeline. Je préfère utiliser des parenthèses pour un contrôle explicite, une auto-documentation, etc. Cela fonctionne sans eux, mais dans quelle mesure faites-vous confiance à cela?

-Replace est un opérateur de comparaison qui accepte un object et retourne un object présumé modifié. C’est pourquoi vous pouvez les emstackr ou les imbriquer comme indiqué ci-dessus.

S’il te plait regarde:

 help about_operators