PowerShell Replace를 사용하여 텍스트 바꾸는 방법 [예제]

많은 다른 언어들과 마찬가지로 PowerShell은 문자열과 텍스트를 다룰 수 있습니다. 그 중 하나인 PowerShell을 사용하여 문자, 문자열 또는 파일 내부의 텍스트를 대체하는 유용한 기능이 있습니다.

이 튜토리얼에서는 PowerShell의 replace() 메소드와 PowerShell의 replace 연산자를 사용하는 방법을 배우게 될 것입니다. 이 튜토리얼은 기본 사항을 다루며 “재미있는” 정규 표현식까지 다룰 것입니다!

시작하기 전에

이 튜토리얼의 모든 예제를 따라하기 위해 많은 것이 필요하지 않습니다. PowerShell만 있으면 됩니다. 이 튜토리얼의 예제는 PowerShell v7.0.2를 사용하지만 모든 예제는 Windows PowerShell에서도 작동해야 합니다.

문자열 대체를 위해 PowerShell 사용하기: 기본 사항

PowerShell 대체를 사용하는 가장 간단한 경우는 문자열 내의 문자를 대체하는 것입니다. 몇 가지 예제로 시작해 보겠습니다.

PowerShell에서 값이 hello, world인 문자열이 있다고 가정해 보겠습니다.

$string = 'hello, world'

그 문자열 내의 문자열 hello를 문자열 hi로 대체하여 $string 변수의 값이 hi, world가 되도록 하고 싶습니다. 이를 위해 PowerShell은 먼저 “찾을” 텍스트가 있는 위치를 찾은 다음 해당 텍스트를 사용자가 정의한 값으로 대체합니다.

Using the Replace() Method

PowerShell replace 명령 방법 중 가장 쉬운 방법 중 하나는 다음과 같이 replace() 메서드를 사용하여 문자열을 교체하는 것입니다.

replace() 메서드는 두 개의 인수를 갖고 있습니다. 찾을 문자열과 찾은 텍스트를 대체할 문자열입니다.아래에서 볼 수 있듯이 PowerShell은 문자열 hello를 찾아 그 문자열을 hi로 대체합니다.그런 다음 메서드는 최종 결과를 반환하며 이는 hi, world입니다.

PS> $string.replace('hello','hi')
hi, world

PowerShell replace 메서드를 사용하여 어떤 문자열이든 다른 문자열로 대체할 수 있습니다. 대체할 문자열이 없으면 replace() 메서드는 아무것도 반환하지 않습니다.

replace() 메서드를 사용하여 문자열에서 텍스트를 교체하려면 변수에 문자열을 할당할 필요가 없습니다. 대신에 직접 문자열에 replace() 메서드를 호출할 수 있습니다. 예: 'hello world'.replace('hello','hi'). 튜토리얼에서는 편의를 위해 변수를 사용하고 있습니다.

문자 제거

문자열에서 다른 문자열로 교체하는 대신에 문자를 제거하고 싶을 수도 있습니다. 빈 문자열을 지정하여 이를 수행할 수 있습니다.

PS> $string.replace('hello','')
, world

여러 인스턴스 교체

이제 다른 문자열 내에서 문자열을 교체하는 코드가 있습니다. 그렇다면 여러 문자열을 교체하는 것은 어떨까요? 문제 없습니다.

PowerShell replace 메서드가 문자열을 반환하므로 다른 인스턴스를 교체하려면 원본의 출력에 다른 replace() 메서드 호출을 추가할 수 있습니다. 그럼 PowerShell은 원래의 출력에 replace() 메서드를 호출합니다.

PS> $string.replace('hello','').replace('world','earth')
, earth

당신은 필요한 만큼 많은 replace() 메서드 호출을 연결할 수 있지만, 많은 문자열을 대체해야 할 경우 replace 연산자를 사용하는 것이 좋습니다.

PowerShell 대체 연산자 사용

PowerShell 대체 문자열 메서드를 사용하는 것이 텍스트를 대체하는 가장 간단한 방법이지만, PowerShell replace 연산자도 사용할 수 있습니다. replace 연산자는 찾아 바꿀 문자열을 제공하는 메서드와 유사합니다. 그러나 한 가지 큰 장점이 있습니다. 정규 표현식(정규식)을 사용하여 일치하는 문자열을 찾을 수 있다는 점입니다(나중에 자세히 설명합니다).

위의 예제를 사용하여 replace 연산자를 사용하여 아래와 같이 hellohi로 대체할 수 있습니다. PowerShell은 동일한 단계를 수행합니다.

PS> $string -replace 'hello','hi'
hi, world

문자 제거

PowerShell 대체 메서드와 마찬가지로, replace 연산자를 사용하여 문자열에서 문자를 제거할 수도 있습니다. 그러나 replace() 메서드와 달리, 대체할 문자열을 인수로 전달하지 않고 완전히 제외할 수도 있으며 동일한 효과를 발견할 수 있습니다.

PS> $string -replace 'hello',''
, world
PS> $string -replace 'hello'
, world

여러 인스턴스 대체

replace() 메서드와 마찬가지로, replace 연산자의 사용법을 연결할 수도 있습니다. replace 연산자가 아래에 표시된대로 문자열을 반환하므로 다음 섹션에서 정규식을 사용하면 코드가 더 깔끔해질 것입니다.

PS> $string -replace 'hello','hi' -replace 'world','earth'
hi, earth

PowerShell 정규식 대체 사용하기

위에서 언급한 대로 PowerShell 대체 메소드를 사용하여 문자열을 대체할 수 있지만, 제한이 있습니다. 문자열 리터럴만 사용할 수 있습니다. 와일드카드나 정규식을 사용할 수는 없습니다. 중간 또는 고급 대체를 수행하는 경우, replace 연산자를 사용해야 합니다.

변수로 생성된 문자열이 포함된 스크립트가 있다고 가정해 봅시다. 해당 문자열은 hello, world 또는 hi, world. 중 하나여야 합니다. 아마도 시스템 관리자로써 나쁜 하루를 보내고 있어서 문자열을 어떤 값이든 상관없이 goodbye, world로 변경하고 싶습니다.

hello, worldhi, world가 모두 goodbye, world로 변환되어야 합니다. 이를 위해 정규식을 사용해야 합니다. 정규식을 사용하면 텍스트에서 거의 모든 특정 패턴을 매칭할 수 있습니다.

이 예제에서는 정규식 “or” (|) 문자를 사용하여 필요한 두 문자열을 모두 매칭할 수 있습니다. 아래에서 확인할 수 있습니다.

PS> 'hello, world' -replace 'hello|hi','goodbye'
goodbye, world
PS> 'hi, world' -replace 'hello|hi','goodbye'   
goodbye, world

문자열을 찾기 위해 regex를 사용하는 방법을 익힌 후에는 PowerShell을 사용하여 어떤 패턴과 일치하는 와일드카드 문자열을 대체할 수 있습니다.

Regex 문자 이스케이프하기

위의 정규식 예제에서는 검색 대상 문자열에 정규식 특수 문자가 포함되어 있지 않았습니다. 정규 표현식 언어에는 대부분의 문자와 숫자처럼 글자 그대로 해석되지 않는 특정한 문자가 있습니다.

예를 들어, 문자열에서 텍스트를 대체해야 할 수 있습니다. 해당 문자열에는 대괄호와 물음표와 같은 몇 개의 정규식 특수 문자가 포함되어 있습니다. 그런 다음 아래에 표시된대로 문자열 [hello]goodbye로 대체하려고 시도합니다.

PS> '[hello], world' -replace '[hello]','goodbye'
[goodbyegoodbyegoodbyegoodbyegoodbye], wgoodbyergoodbyed

이는 분명히 의도한 바가 아닙니다. 이러한 상황은 문자열 내에서 정규식 특수 문자를 사용할 때 발생합니다 ([hello]).

이 문제를 피하려면 두 가지 옵션이 있습니다. 각 문자 앞에 백슬래시를 추가하여 이러한 특수 문자를 이스케이프하거나 Escape() 메소드를 사용할 수 있습니다.

아래에서는 각 특수 문자를 백슬래시로 이스케이프한 효과를 볼 수 있습니다.

PS> '[hello], world' -replace '\[hello\]','goodbye'
goodbye, world

또는 대안으로 권장되는 대로 정규식 유형의 Escape() 메소드를 사용하여 자동으로 모든 특수 문자를 제거할 수 있습니다.

PS> '[hello], world' -replace ([regex]::Escape('[hello]')),'goodbye'
goodbye, world

가능한 경우 Escape() 메소드를 사용해야 합니다. 왜냐하면 이렇게 하면 모든 특수 문자를 기억하지 않아도 되기 때문입니다.

매치/캡처 그룹 사용

이전 예제들 중에서 이 튜토리얼은 다른 문자열로 대체하기 위해 리터럴 문자열을 사용해왔습니다. hi 또는 goodbye를 사용했습니다. 하지만 PowerShell에서 찾은 문자열을 대체로 사용하고 싶다면 어떻게 해야 할까요? 이때는 일치 또는 캡처 그룹을 사용해야 합니다.

정규식에는 캡처 그룹과 역참조라는 개념이 있습니다. 캡처 그룹을 사용하여 다른 곳에서 참조할 수 있는 문자열을 캡처할 수 있습니다. PowerShell은 replace 연산자와 함께 매치 그룹을 활용합니다.

예를 들어, 몇 가지 다른 값을 포함할 수 있는 문자열이 있다고 가정해 보겠습니다.

'hello world, you sexy beast'
'hi world, now go away'
'hello earth, you are lovely today'

문자열의 첫 부분과 두 번째 부분을 서로 교체하고 싶습니다. 결과는 다음과 같이 보여야 합니다:

'you sexy beast,hello world'
'now go away,hi world'
'you are lovely today,hello earth'

이 작업을 수행하기 위해 PowerShell은 쉼표의 오른쪽과 왼쪽의 모든 텍스트를 찾아야 합니다. 그 텍스트가 무엇인지 알게 되면, 한 쪽을 다른 쪽으로 대체해야 합니다. 이를 위해 역참조가 필요합니다.

A backreference is a regex variable (not a PowerShell variable) that represents the text that regex matched. Backreferences in PowerShell are represented with a dollar sign followed by a number indicating the order in which they were matched.

아래 예제를 확인할 수 있습니다.

## 이 문자열은 다음과 같을 수도 있습니다:
## 'hi, world, now go away'
## 'hello, earth, you are lovely today'
PS> $string = 'hello, world, you sexy beast'
PS> $string -replace '(.*), (.*)','$2,$1'
you sexy beast,hello world

위의 예제에서는 각 일치 항목(hello world)과 (you sexy beast)를 괄호로 둘러싼 정규식 캡처 그룹을 볼 수 있습니다. 그런 다음 대체 작업에서 hello word가 가장 왼쪽에서 오른쪽으로 일치하기 때문에 $1 백 레퍼런스 레이블을, you sexy beast$2 백 레퍼런스 레이블을 받습니다.

Powershell이 각 일치 항목의 값을 알고 있는 경우, 이러한 참조를 대체 텍스트에서 원하는 방식으로 사용할 수 있습니다. 이 예제에서는 $2,$1이 위치를 바꿉니다.

이름 있는 일치 그룹 사용

매치 값을 참조하기 위해 $1, $2와 같은 숫자 플레이스홀더를 사용하지 않고 레이블 또는 이름을 사용할 수도 있습니다. 각 참조가 무엇을 의미하는지 왼쪽에서 오른쪽으로 세어야 하는 번거로움 없이 간단히 이름을 사용할 수 있습니다.

이름을 참조로 사용하려면, 먼저 일치 문자열에서 각 매치에 대한 레이블을 정의해야 합니다. 이를 위해 캡처 그룹을 (?<label><regex>)와 같이 정의해야 합니다. 여기서 label은 이름이고 <regex>는 사용 중인 정규식입니다.

이름을 정의한 후에는 대체 문자열에서 달러 기호를 사용하여 이름을 중괄호로 둘러싸는 방식으로 참조할 수 있습니다. 예를 들어 ${label}입니다.

아래에서 이 기술의 데모를 볼 수 있습니다.

PS> $string = 'hello, world, you sexy beast'
PS> $string -replace '(?<First_Part>.*), (?<Second_Part>.*)','${Second_Part},${First_Part}'
you sexy beast,hello, world

결론

다음과 같이 배웠듯이 PowerShell 대체 연산자를 사용하면 다양한 방법으로 문자, 텍스트 및 문자열을 대체할 수 있습니다. 간단한 대체를 수행하려면 replace() 메서드를 사용할 수 있지만 더 고급적인 대체가 필요한 경우 항상 replace 연산자를 사용하세요.

Source:
https://adamtheautomator.com/powershell-replace/