J'écris un script pour personnaliser un fichier de configuration. Je souhaite remplacer plusieurs instances de chaînes dans ce fichier et j'ai essayé d'utiliser PowerShell pour effectuer le travail.
Cela fonctionne bien pour un seul remplacement, mais effectuer plusieurs remplacements est très lent car chaque fois, il doit analyser à 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 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 à chaîner le -replace
opérations ensemble. Le `
à la fin de chaque ligne échappe à la nouvelle ligne, ce qui permet à PowerShell de continuer à analyser l’expression de 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’attribuer une variable intermédiaire:
$x = $_ -replace 'something1', 'something1aa'
$x = $x -replace 'something2', 'something2bb'
...
$x
Pour que la publication de George Howarth fonctionne correctement avec plusieurs remplaçants, vous devez supprimer la rupture, affecter le résultat à une variable ($ line), puis générer la variable suivante:
$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
Avec la version 3 de PowerShell, vous pouvez chaîner les appels de remplacement:
(Get-Content $sourceFile) | ForEach-Object {
$_.replace('something1', 'something1').replace('somethingElse1', 'somethingElse2')
} | Set-Content $destinationFile
En supposant que vous ne pouvez avoir qu'un seul 'something1'
ou 'something2'
, etc., par ligne, vous pouvez utiliser une table de correspondance:
$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 plusieurs, supprimez simplement break
dans l'instruction if
.
Une troisième option, pour une doublure en pipeline, consiste à imbriquer les remplacements:
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 le contrôle explicite, l'auto-documentation, etc. Cela fonctionne sans elles, mais jusqu'à quel point avez-vous confiance en cela?
-Replace est un opérateur de comparaison qui accepte un objet et retourne un objet probablement modifié. C'est pourquoi vous pouvez les empiler ou les imbriquer comme indiqué ci-dessus.
S'il te plait regarde:
help about_operators