ניהול קבצי טקסט: כיצד לקרוא ולערוך עם PowerShell

צריך לדעת איך להשתמש ב- PowerShell כדי לקרוא קובץ טקסט ולהחליף טקסט? זה מה שאנחנו קוראים לזה ב- PowerShell Read-Text File.

אל תחפש יותר! פוסט הבלוג הזה הוא בשבילך. עד סוף הפוסט, אני אראה לך פונקציה שבניתי שתשפר את חייך הרבה.

להחלפת טקסט בקובץ באמצעות PowerShell זה תהליך של שלוש שלבים.

  1. קריאת הקובץ
  2. מציאת והחלפת המחרוזת
  3. כתיבת השינויים לקובץ.

קריאת הקובץ

תצטרך תחילה לקרוא את הקובץ. נבנה תחילה קובץ עם פקודת ה- Set-Content כך שיהיה לנו קובץ לעבוד עם.

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

כדי לקרוא את הקובץ הזה, ניתן להשתמש בפקודת Get-Content. תוכל לקרוא את הקובץ על ידי מתן נתיב קובץ טקסט לפרמטר Path כפי שמוצג למטה.

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

מציאת והחלפת המחרוזת

עכשיו שיש לנו את תוכן הקובץ בזיכרון במחרוזת, עלינו לחפש ולהחליף את המחרוזת. דרך אחת לעשות זאת היא להשתמש באופרטור -replace. אופרטור זה של PowerShell מוצא מחרוזת ומחליפה אותה באחרת.

על ידי שימוש בתוכן הקובץ המופיע בדוגמה, ניתן לספק את מחרוזת החיפוש foo עם מחרוזת ההחלפה bar שכן תעשה את תוכן הקובץ foo foo baz כעת.

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

כתיבה לקובץ

עכשיו שיש לנו את תוכן הקובץ החדש שנשמר ב-$newContent, נוכל כעת לכתוב את התוכן הזה בחזרה לקובץ. אחת הדרכים לעשות זאת היא להשתמש בפקודה Set-Content.

הפקודה Set-Content מחליף את כל תוכן הקובץ ומשווה לו ערך חדש.

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

כשתקרא עכשיו את הקובץ C:\file.txt עם Get-Content, תראה שהוא מכיל כעת את התוכן החדש.

טיפול בטיפולי קבצים פתוחים

השלבים שעברת עד כה עובדים… ברוב המקרים. אך, תגלה שבעולם האמיתי, זה לא תמיד יתרחש כך.

תגלה שמדי פעם עליך להתמודד עם קבצים שפתוחים בפועל על ידי PowerShell עצמו. זה מונע ממך לכתוב את התוכן החדש בחזרה לקובץ.

כדי לטפל במצב הזה של יידיד קבצים פתוחים, יצרתי תהליך פשוט שמאפשר לך ליצור קובץ טקסט זמני על הדיסק תחילה עם התוכן החדש, להסיר את הקובץ המקורי ולאחר מכן לשנות את שם הקובץ הזמני.

כאן דוגמה לאיך זה עובד:

$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

למטה יש דוגמה לפונקציה שבניתי בשם Find-InTextFile שמשתמשת בשיטה זו בשילוב עם היכולת למצוא (ולא להחליף) טקסט בקובץ.

פונקציה זו גם משתמשת בתחביר הביטויים הרגולריים היעילים יותר למציאת מחרוזות. תגלה שבאמצעות ביטויים רגולריים ניתן לבצע חיפושים גמישים יותר באמצעות תווים מיוחדים כמו גרשיים, תווים מיוחדים ועוד.

אתה יכול גם לראות מטה שאני משתמש בלולאת foreach כדי לעבד קבצים מרובים בו זמנית. זה מועיל אם יש לך המון קבצים לעיבוד.

function Find-InTextFile {
    <#
    .SYNOPSIS
        ביצוע חיפוש (או החלפה) במחרוזת בקובץ טקסט או קבצים.
    .EXAMPLE
        PS> מצא-בתוךקובץטקסט -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine'
    
        מחליף את כל המופעים של המחרוזת 'water' לתוך המחרוזת 'wine' ב
        'C:\MyFile.txt'.
    .EXAMPLE
        PS> מצא-בתוךקובץטקסט -FilePath 'C:\MyFile.txt' -Find 'water'
    
        מוצא את כל המופעים של המחרוזת 'water' בקובץ 'C:\MyFile.txt'.
    .PARAMETER FilePath
        נתיב הקובץ של הקובץ הטקסט שבו תרצה לבצע חיפוש/החלפה.
    .PARAMETER Find
        המחרוזת שברצונך להחליף.
    .PARAMETER Replace
        המחרוזת שברצונך להחליף את המחרוזת 'Find' שלך בה.
    .PARAMETER NewFilePath
        אם נדרש יצירת קובץ חדש עם המחרוזת המוחלפת במקום להחליף
        את תוכן הקובץ הקיים, השתמש בפרמטר זה ליצירת קובץ חדש.
    .PARAMETER Force
        אם נעשה שימוש בפרמטר NewFilePath, שימוש בפרמטר זה ידרוס כל קובץ
        שקיים ב- 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
        }
    }
}

משאבים

למידע נוסף על פקודת Set-Content ראה Set-Content: דרך PowerShell לכתיבה לקובץ או דרך אלטרנטיבית לכתיבת תוכן לקובץ, פקודת Out-File.

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