Gestion des fichiers texte : Comment lire et modifier avec PowerShell

Besoin de savoir comment utiliser PowerShell pour lire un fichier texte et remplacer du texte ? C’est ce que nous appelons la lecture de fichiers texte PowerShell.

Ne cherchez pas plus loin ! Ce billet de blog est pour vous. À la fin du billet, je vous montrerai une fonction que j’ai créée pour rendre votre vie beaucoup plus facile.

Remplacer du texte dans un fichier avec PowerShell est un processus en trois étapes.

  1. Lecture du fichier
  2. Recherche et remplacement de la chaîne
  3. Écriture des modifications dans le fichier.

Lecture du fichier

Vous devez d’abord lire le fichier. Commençons par en créer un avec la cmdlet Set-Content afin d’avoir un fichier avec lequel travailler.

Set-Content -Path 'C:\file.txt' -Value 'foo bar baz'

Pour lire ce fichier, vous pouvez utiliser la commande Get-Content. Vous pouvez lire le fichier en fournissant un chemin de fichier texte au paramètre Path comme indiqué ci-dessous.

$content = Get-Content -Path 'C:\file.txt'

Recherche et Remplacement de la Chaîne

Maintenant que nous avons le contenu du fichier en mémoire dans une chaîne, nous devons rechercher et remplacer la chaîne. Une façon de le faire est d’utiliser l’opérateur -replace. Cet opérateur PowerShell trouve une chaîne et la remplace par une autre.

En utilisant le contenu du fichier exemple, nous pouvons fournir la chaîne de recherche foo avec la chaîne de remplacement bar ce qui devrait rendre le contenu du fichier foo foo baz maintenant.

PS> $newContent = $content -replace 'foo', 'bar'
bar bar baz

Écriture dans le fichier

Maintenant que nous avons les nouveaux contenus du fichier enregistrés dans $newContent, nous pouvons maintenant écrire ces nouveaux contenus dans le fichier. Une façon de le faire est d’utiliser la commande Set-Content.

La commande Set-Content remplace tous les contenus d’un fichier en assignant une nouvelle valeur.

$newContent | Set-Content -Path 'C:\file.txt'

Lorsque vous lisez maintenant le fichier C:\file.txt avec la commande Get-Content, vous verrez qu’il contient maintenant le nouveau contenu.

Gestion des références de fichiers ouvertes

Les étapes que vous avez précédemment effectuées fonctionnent… la plupart du temps. Cependant, dans le monde réel, cela ne se passe pas toujours ainsi.

Vous constaterez que vous devrez parfois traiter des fichiers qui sont ouverts par PowerShell lui-même. Cela vous empêche d’écrire les nouveaux contenus dans le fichier.

Pour remédier à cette situation de références de fichiers ouvertes, j’ai créé un flux de travail simple qui vous permet de créer d’abord un fichier texte temporaire sur le disque avec les nouveaux contenus, de supprimer le fichier d’origine, puis de renommer le fichier temporaire.

Voici un exemple de son fonctionnement :

$filePath = 'C:\file.txt'
$tempFilePath = "$env:TEMP\$($filePath | Split-Path -Leaf)"
$find = 'foo'
$replace = 'bar'

(Get-Content -Path $filePath) -replace $find, $replace | Add-Content -Path $tempFilePath

Remove-Item -Path $filePath
Move-Item -Path $tempFilePath -Destination $filePath

Voici un exemple d’une fonction que j’ai créée appelée Find-InTextFile qui utilise cette approche combinée à la capacité de trouver (mais pas de remplacer) du texte dans un fichier.

Cette fonction utilise également la syntaxe des expressions régulières plus puissante pour trouver des chaînes. Vous constaterez que les expressions régulières vous permettent de rechercher de manière plus flexible en utilisant des caractères spéciaux comme les guillemets simples, les caractères spéciaux, et plus encore.

Vous pouvez également voir ci-dessous que j’utilise une boucle foreach pour traiter plusieurs fichiers à la fois. Cela est pratique si vous avez une série de fichiers à traiter.

function Find-InTextFile {
    <#
    .SYNOPSIS
        Effectue une recherche (ou un remplacement) sur une chaîne dans un fichier texte ou plusieurs fichiers.
    .EXAMPLE
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine'
    
        Remplace toutes les occurrences de la chaîne 'water' par la chaîne 'wine' dans
        'C:\MyFile.txt'.
    .EXAMPLE
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water'
    
        Recherche toutes les occurrences de la chaîne 'water' dans le fichier 'C:\MyFile.txt'.
    .PARAMETER FilePath
        Le chemin du fichier texte sur lequel vous souhaitez effectuer une recherche/remplacement.
    .PARAMETER Find
        La chaîne que vous souhaitez remplacer.
    .PARAMETER Replace
        La chaîne par laquelle vous souhaitez remplacer votre chaîne 'Find'.
    .PARAMETER NewFilePath
        Si un nouveau fichier avec la chaîne remplacée doit être créé au lieu de remplacer
        le contenu du fichier existant, utilisez ce paramètre pour créer un nouveau fichier.
    .PARAMETER Force
        Si le paramètre NewFilePath est utilisé, l'utilisation de ce paramètre écrasera tout fichier
        existant dans NewFilePath.
    #>
    [CmdletBinding(DefaultParameterSetName = 'NewFile')]
    [OutputType()]
    param (
        [Parameter(Mandatory = $true)]
        [ValidateScript({Test-Path -Path $_ -PathType 'Leaf'})]
        [string[]]$FilePath,
        [Parameter(Mandatory = $true)]
        [string]$Find,
        [Parameter()]
        [string]$Replace,
        [Parameter(ParameterSetName = 'NewFile')]
        [ValidateScript({ Test-Path -Path ($_ | Split-Path -Parent) -PathType 'Container' })]
        [string]$NewFilePath,
        [Parameter(ParameterSetName = 'NewFile')]
        [switch]$Force
    )
    begin {
        $Find = [regex]::Escape($Find)
    }
    process {
        try {
            foreach ($File in $FilePath) {
                if ($Replace) {
                    if ($NewFilePath) {
                        if ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and $Force.IsPresent) {
                            Remove-Item -Path $NewFilePath -Force
                            (Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force
                        } elseif ((Test-Path -Path $NewFilePath -PathType 'Leaf') -and !$Force.IsPresent) {
                            Write-Warning "The file at '$NewFilePath' already exists and the -Force param was not used"
                        } else {
                            (Get-Content $File) -replace $Find, $Replace | Add-Content -Path $NewFilePath -Force
                        }
                    } else {
                        (Get-Content $File) -replace $Find, $Replace | Add-Content -Path "$File.tmp" -Force
                        Remove-Item -Path $File
                        Move-Item -Path "$File.tmp" -Destination $File
                    }
                } else {
                    Select-String -Path $File -Pattern $Find
                }
            }
        } catch {
            Write-Error $_.Exception.Message
        }
    }
}

Ressources

Pour plus d’informations sur la commande Set-Content, consultez Set-Content : La manière PowerShell d’écrire dans un fichier ou une autre façon d’écrire du contenu dans un fichier, la commande Out-File.

Source:
https://adamtheautomator.com/powershell-read-text-file/