Bestandsbeheer: Hoe te lezen en bewerken met PowerShell

Moet weten hoe u PowerShell kunt gebruiken om een tekstbestand te lezen en tekst te vervangen? Dit is wat we de PowerShell Read-Text File noemen.

Zoek niet verder! Deze blogpost is voor jou. Tegen het einde van de post laat ik je een functie zien die ik heb gebouwd om je leven veel gemakkelijker te maken.

Het vervangen van tekst in een bestand met PowerShell is een proces van drie stappen.

  1. Het bestand lezen
  2. De string vinden en vervangen
  3. De wijzigingen naar het bestand schrijven.

Het bestand lezen

U moet eerst het bestand lezen. Laten we eerst een bestand maken met behulp van de Set-Content cmdlet zodat we er een hebben om mee te werken.

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

Om dit bestand te lezen, kunt u de Get-Content opdracht gebruiken. U kunt het bestand lezen door een tekstbestandspad op te geven aan de Path parameter zoals hieronder weergegeven.

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

De string vinden en vervangen

Nu we de inhoud van het bestand in het geheugen hebben als een string, moeten we de string zoeken en vervangen. Een manier om dat te doen is door de -replace operator te gebruiken. Deze PowerShell operator zoekt een string en vervangt deze door een andere.

Met behulp van de voorbeeldbestandsinhoud kunnen we de zoekstring foo vervangen door de vervangende string bar, wat de bestandsinhoud nu foo foo baz zou maken.

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

Schrijven naar het bestand

Nu we de nieuwe bestandsinhoud opgeslagen hebben in $newContent, kunnen we deze nieuwe inhoud nu terug schrijven naar het bestand. Een manier om dat te doen is door gebruik te maken van het Set-Content commando.

Het Set-Content commando vervangt alle inhoud van een bestand door een nieuwe waarde toe te kennen.

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

Wanneer je nu het bestand C:\file.txt leest met Get-Content, zul je zien dat het nu de nieuwe inhoud bevat.

Omgaan met Open Bestandshandles

De stappen die je eerder hebt doorlopen werken… meestal. Echter, je zult in de echte wereld merken dat het niet altijd zo uitpakt.

Je zult af en toe te maken krijgen met bestanden die open zijn in PowerShell zelf. Dit voorkomt dat je de nieuwe inhoud terug kunt schrijven naar het bestand.

Om deze situatie met een open bestandshandle op te lossen, heb ik een eenvoudige workflow gemaakt die je in staat stelt eerst een tijdelijk tekstbestand op schijf aan te maken met de nieuwe inhoud, het oorspronkelijke bestand te verwijderen en vervolgens het tijdelijke bestand te hernoemen.

Hier is een voorbeeld van hoe het werkt:

$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

Hieronder staat een voorbeeld van een functie die ik heb gebouwd genaamd Find-InTextFile die deze aanpak gebruikt in combinatie met de mogelijkheid om tekst in een bestand te vinden (niet te vervangen).

Deze functie maakt ook gebruik van de krachtigere syntaxis van reguliere expressies om strings te vinden. Je zult merken dat reguliere expressies je in staat stellen om flexibeler te zoeken met behulp van speciale karakters zoals enkele aanhalingstekens, speciale karakters en meer.

Je kunt ook hieronder zien dat ik een foreach-lus gebruik om meerdere bestanden tegelijk te verwerken. Dit is handig als je een heleboel bestanden moet verwerken.

function Find-InTextFile {
    <#
    .SAMENVATTING
        Voert een zoekopdracht (of vervanging) uit op een string in een tekstbestand of -bestanden.
    .VOORBEELD
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine'
    
        Vervangt alle voorkomens van de string 'water' door de string 'wine' in
        'C:\MyFile.txt'.
    .VOORBEELD
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water'
    
        Zoekt alle voorkomens van de string 'water' in het bestand 'C:\MyFile.txt'.
    .PARAMETER FilePath
        Het bestandspad van het tekstbestand waarop je een zoekopdracht/vervanging wilt uitvoeren.
    .PARAMETER Find
        De string die je wilt vervangen.
    .PARAMETER Replace
        De string waarmee je je 'Find'-string wilt vervangen.
    .PARAMETER NewFilePath
        Als er een nieuw bestand met de vervangen string moet worden gemaakt in plaats van het vervangen
        van de inhoud van het bestaande bestand, gebruik dan deze parameter om een nieuw bestand te maken.
    .PARAMETER Force
        Als de parameter NewFilePath wordt gebruikt, zal het gebruik van deze parameter elk bestand overschrijven dat
        bestaat in 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
        }
    }
}

Resources

Voor meer informatie over het Set-Content-commando kun je kijken naar Set-Content: De PowerShell-manier om naar een bestand te schrijven of een alternatieve manier om inhoud naar een bestand te schrijven, het Out-File-commando.

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