Script PowerShell pour trouver et remplacer tous les fichiers avec une Extension spécifique
j'ai plusieurs fichiers de configuration sur Windows Server 2008 imbriqués comme ceci:
C:ProjectsProject_1project1.config
C:ProjectsProject_2project2.config
dans ma configuration je dois faire une chaîne de caractères remplacer comme ceci:
<add key="Environment" value="Dev"/>
deviendra:
<add key="Environment" value="Demo"/>
j'ai pensé à utiliser des scripts par lots, mais il n'y avait pas de bonne façon de le faire, et j'ai entendu dire qu'avec PowerShell scripting vous pouvez facilement exécuter ceci. J'ai trouvé des exemples de rechercher/remplacer, mais j'espérais pour une façon qui traverserait tous les dossiers à l'intérieur de mon C:Projects répertoire et trouver tous les fichiers qui se terminent par le '.config ' extension. Quand il en trouve un, je veux remplacer ma chaîne de valeurs.
de bonnes ressources pour savoir comment faire ceci ou n'importe quel gurus PowerShell qui peut offrir une certaine perspicacité?
8 réponses
Voici une première tentative au-dessus de ma tête.
$configFiles = Get-ChildItem . *.config -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace "Dev", "Demo" } |
Set-Content $file.PSPath
}
PowerShell est un bon choix ;) il est très facile d'énumérer des fichiers dans un répertoire donné, de les lire et de les traiter.
le script pourrait ressembler à ceci:
Get-ChildItem C:\Projects *.config -recurse |
Foreach-Object {
$c = ($_ | Get-Content)
$c = $c -replace '<add key="Environment" value="Dev"/>','<add key="Environment" value="Demo"/>'
[IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
}
je divise le code à plus de lignes pour être lisible pour vous.
Notez que vous pouvez utiliser Set-Content au lieu de [IO.File]::WriteAllText
, mais il ajoute une nouvelle ligne à la fin. Avec WriteAllText
vous pouvez l'éviter.
sinon le code pourrait ressembler à ceci: $c | Set-Content $_.FullName
.
Cette approche fonctionne bien:
gci C:\Projects *.config -recurse | ForEach {
(Get-Content $_ | ForEach {$_ -replace "old", "new"}) | Set-Content $_
}
- changer" ancien "et" nouveau " à leurs valeurs correspondantes (ou utiliser des variables).
- N'oubliez pas la parenthèse -- sans laquelle vous recevrez une erreur d'accès.
j'utiliserais xml et xpath:
dir C:\Projects\project_*\project*.config -recurse | foreach-object{
$wc = [xml](Get-Content $_.fullname)
$wc.SelectNodes("//add[@key='Environment'][@value='Dev']") | Foreach-Object {$_.value = 'Demo'}
$wc.Save($_.fullname)
}
cet exemple powershell recherche toutes les instances de la chaîne "\foo\ "dans un dossier et ses sous-dossiers, remplace" \foo\ "par" \bar\ "et ne réécrit pas les fichiers qui ne contiennent pas la chaîne" \foo\ "de cette façon, vous ne détruisez pas le fichier date de dernière mise à jour timbres où la chaîne n'a pas été trouvée:
Get-ChildItem -Path C:\YOUR_ROOT_PATH\*.* -recurse
| ForEach {If (Get-Content $_.FullName | Select-String -Pattern '\foo\')
{(Get-Content $_ | ForEach {$_ -replace '\foo\', '\bar\'}) | Set-Content $_ }
}
j'ai trouvé le commentaire de @Artyom utile, mais malheureusement il n'a pas posté de réponse.
C'est la version courte, à mon avis la meilleure version, de la accepté de répondre;
ls *.config -rec | %{$f=$_; (gc $f.PSPath) | %{$_ -replace "Dev", "Demo"} | sc $f.PSPath}
j'ai écrit une petite fonction d'aide pour remplacer le texte dans un fichier:
function Replace-TextInFile
{
Param(
[string]$FilePath,
[string]$Pattern,
[string]$Replacement
)
[System.IO.File]::WriteAllText(
$FilePath,
([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement)
)
}
exemple:
Get-ChildItem . *.config -rec | ForEach-Object {
Replace-TextInFile -FilePath $_ -Pattern 'old' -Replacement 'new'
}
lors d'un remplacement récursif, le chemin et le nom du fichier doivent être inclus:
Get-ChildItem -Recurse | ForEach { (Get-Content $_.PSPath |
ForEach {$ -creplace "old", "new"}) | Set-Content $_.PSPath }
ceci remplacera tout" ancien "par" nouveau " sensible à la casse dans tous les fichiers de vos dossiers de votre répertoire courant.