텍스트 파일 관리: PowerShell로 읽고 편집하는 방법

텍스트 파일을 읽고 텍스트를 대체하는 PowerShell 사용 방법을 알고 싶나요? 이를 PowerShell Read-Text File이라고 합니다.

더 이상 찾아볼 필요가 없습니다! 이 블로그 포스트는 여러분을 위한 것입니다. 이 글의 끝에서는 여러분의 일을 훨씬 쉽게 만들어 줄 함수를 소개해 드릴 것입니다.

파일에서 텍스트를 대체하는 것은 세 단계 과정입니다.

  1. 파일 읽기
  2. 문자열 찾아 대체
  3. 변경 사항 파일에 쓰기.

파일 읽기

먼저 파일을 읽어야 합니다. 먼저 Set-Content cmdlet를 사용하여 파일을 만들어 둡시다.

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

이 파일을 읽으려면 Path 매개변수에 텍스트 파일 경로를 제공하여 Get-Content 명령을 사용할 수 있습니다. 아래와 같이 텍스트 파일 경로를 제공하여 파일을 읽을 수 있습니다.

$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'

이제 Get-Content를 사용하여 C:\file.txt 파일을 읽으면 새로운 내용이 포함되어 있는 것을 볼 수 있습니다.

열린 파일 핸들 다루기

이전에 수행한 단계는 대부분의 경우 작동합니다. 그러나 실제 세계에서는 항상 그렇지 않을 수 있습니다.

가끔 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> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water' -Replace 'wine'
    
        'C:\MyFile.txt'의 모든 'water' 문자열을 'wine'으로 바꿉니다.
    .EXAMPLE
        PS> Find-InTextFile -FilePath 'C:\MyFile.txt' -Find 'water'
    
        'C:\MyFile.txt' 파일에서 'water' 문자열을 찾습니다.
    .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 명령어를 참고하세요. 파일에 쓰기 위한 PowerShell 방식인 Set-Content: The PowerShell Way to Write to a File을 확인하거나 파일에 내용을 쓰는 다른 방법으로 Out-File 명령어를 사용할 수 있습니다.

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