Gestione dei file di testo: come leggere e modificare con PowerShell

Hai bisogno di sapere come utilizzare PowerShell per leggere un file di testo e sostituire del testo? Questo è quello che chiamiamo PowerShell Read-Text File.

Non cercare oltre! Questo post sul blog è per te. Alla fine del post, ti mostrerò una funzione che ho creato per rendere la tua vita molto più facile.

La sostituzione del testo in un file con PowerShel è un processo in tre fasi.

  1. Lettura del file
  2. Trovare e sostituire la stringa
  3. Scrittura delle modifiche nel file.

Lettura del file

Prima devi leggere il file. Creiamo prima uno con il cmdlet Set-Content così ne abbiamo uno con cui lavorare.

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

Per leggere questo file, puoi utilizzare il comando Get-Content. Puoi leggere il file fornendo il percorso del file di testo al parametro Path come mostrato di seguito.

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

Trovare e sostituire la stringa

Ora che abbiamo il contenuto del file in memoria in una stringa, dobbiamo cercare e sostituire la stringa. Un modo per farlo è utilizzare l’operatore -replace. Questo operatore di PowerShell trova una stringa e la sostituisce con un’altra.

Utilizzando il contenuto di esempio del file, possiamo fornire la stringa di ricerca foo con la stringa di sostituzione bar che dovrebbe rendere il contenuto del file foo foo baz ora.

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

Scrittura nel file

Ora che abbiamo i nuovi contenuti del file salvati in $newContent, dobbiamo scrivere questi nuovi contenuti nel file. Un modo per farlo è utilizzare il comando Set-Content.

Il comando Set-Content sostituisce tutti i contenuti di un file assegnando un nuovo valore.

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

Ogni volta che leggi il file C:\file.txt con Get-Content, vedrai che ora contiene il nuovo contenuto.

Gestione degli handle dei file aperti

I passaggi che hai eseguito in precedenza funzionano… nella maggior parte dei casi. Tuttavia, nella vita reale, non sempre è così.

Capiterà che dovrai occasionalmente gestire file aperti da PowerShell stesso. Ciò impedisce di scrivere i nuovi contenuti nel file.

Per rimediare a questa situazione di gestione degli handle dei file aperti, ho creato un semplice flusso di lavoro che consente di creare prima un file di testo temporaneo su disco con i nuovi contenuti, rimuovere il file originale e quindi rinominare il file temporaneo.

Ecco un esempio di come funziona:

$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

Di seguito è riportato un esempio di una funzione che ho creato chiamata Find-InTextFile che utilizza questo approccio combinato con la capacità di trovare (non sostituire) il testo in un file.

Questa funzione utilizza anche la sintassi delle espressioni regolari più potente per trovare stringhe. Le espressioni regolari ti consentiranno di effettuare ricerche più flessibili utilizzando caratteri speciali come virgolette singole, caratteri speciali e altro ancora.

Puoi anche vedere qui sotto che sto usando un ciclo foreach per elaborare più file contemporaneamente. Questo è utile se hai un sacco di file da elaborare.

function Find-InTextFile {
    <#
    .SINOPSIS
        Esegue una ricerca (o sostituzione) su una stringa in un file di testo o in file.
    .ESEMPIO
        PS> Find-InTextFile -FilePath 'C:\MioFile.txt' -Find 'acqua' -Replace 'vino'
    
        Sostituisce tutte le occorrenze della stringa 'acqua' con la stringa 'vino' in
        'C:\MioFile.txt'.
    .ESEMPIO
        PS> Find-InTextFile -FilePath 'C:\MioFile.txt' -Find 'acqua'
    
        Trova tutte le occorrenze della stringa 'acqua' nel file 'C:\MioFile.txt'.
    .PARAMETRO FilePath
        Il percorso del file di testo su cui eseguire una ricerca/sostituzione.
    .PARAMETRO Find
        La stringa da sostituire.
    .PARAMETRO Replace
        La stringa con cui sostituire la stringa 'Find'.
    .PARAMETRO NewFilePath
        Se è necessario creare un nuovo file con la stringa sostituita anziché sostituire
        il contenuto del file esistente, utilizzare questo parametro.
    .PARAMETRO Force
        Se viene utilizzato il parametro NewFilePath, utilizzare questo parametro per sovrascrivere
        eventuali file esistenti 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
        }
    }
}

Risorse

Per ulteriori informazioni sul comando Set-Content, consulta Set-Content: il modo PowerShell per scrivere su un file o un modo alternativo per scrivere il contenuto su un file, il comando Out-File.

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