about_Simplified_Syntax — 간단한 구문(Where-Object / ForEach-Object)

about_Simplified_Syntax — 간단한 구문(Where-Object / ForEach-Object)

컬렉션(배열)에 담긴 객체들을 걸러내거나 반복 처리할 때, 매번 scriptblock과 자동 변수 $_를 붙여 쓰는 게 좀 번거롭죠. PowerShell 3.0부터 도입된 간단한 구문(simplified syntax) 을 쓰면 Where-ObjectForEach-Object를 좀 더 자연스러운 문장처럼 작성할 수 있어요. 이 글에서는 그 간단한 구문이 어떻게 작동하는지 예시와 함께 살펴볼게요.

출처: about_Simplified_Syntax

본문

짧은 설명

컬렉션에 담긴 객체들을 걸러내는 필터 명령을 scriptblock 없이 더 쉽고 자연스럽게 작성하는 방법을 설명합니다.

자세한 설명

간단한 구문은 Windows PowerShell 3.0에서 도입됐어요. 이를 쓰면 일부 필터 명령을 scriptblock 없이 만들 수 있죠. 이 구문은 자연어에 가까운 형태라서, 특히 파이프라인을 통해 명령으로 들어오는 객체 컬렉션을 처리할 때 유용합니다. 대상이 되는 명령은 Where-ObjectForEach-Object, 그리고 그에 대응하는 별칭 whereforeach예요.

가장 큰 장점은 컬렉션의 멤버(대부분은 배열)에 대해 메서드를 호출할 때, scriptblock 안에서 자동 변수 $_를 일일이 참조하지 않아도 된다는 점입니다. 아래 두 가지 호출을 비교해 볼게요.

표준 구문(Standard Syntax)

Get-ChildItem Cert:\LocalMachine\Root |
    Where-Object -FilterScript { $_.FriendlyName -eq 'Verisign' }

Get-ChildItem Cert:\ -Recurse |
    ForEach-Object -FilterScript { $_.GetKeyAlgorithm() }

참고로 두 번째 명령에서는 컬렉션 안의 각 객체에 대해 GetKeyAlgorithm 메서드를 호출해요. 그런데 파이프라인에서 받은 객체에 GetKeyAlgorithm 메서드가 없다면, 이 명령은 오류를 만들어 냅니다.

간단한 구문(Simplified Syntax)

간단한 구문에서는 컬렉션 안 객체의 멤버를 대상으로 작동하는 비교 연산자가 파라미터로 구현돼요. 또 scriptblock 안에서 자동 변수 $_를 참조하지 않고도 컬렉션 안 객체의 메서드를 호출할 수 있죠. 위 표준 구문 예시와 아래 두 호출을 비교해 보세요.

Get-ChildItem Cert:\LocalMachine\Root |
    Where-Object -Property FriendlyName -EQ 'Verisign'

Get-ChildItem Cert:\ -Recurse |
    ForEach-Object -MemberName GetKeyAlgorithm

PropertyMemberName 파라미터는 위치 파라미터(positional)기 때문에, 명령에서 생략해도 됩니다. 여기에 별칭까지 쓰면 명령을 더 단순하게 줄일 수 있어요.

dir Cert:\LocalMachine\Root | where FriendlyName -EQ 'Verisign'
dir Cert:\ -Recurse | foreach GetKeyAlgorithm

두 구문 모두 동작하지만, 간단한 구문은 scriptblock 안에서 자동 변수 $_를 참조하지 않고도 결과를 얻어냅니다. 그래서 자연어 문장처럼 읽히고, 이해하기가 더 쉬워요.

여기서 메서드 이름 GetKeyAlgorithm은 ForEach-Object의 MemberName 파라미터에 인자로 전달되는 값이에요. 간단한 구문으로 메서드를 호출하면, 파이프라인 안의 객체가 해당 메서드를 가진 경우에만 각 객체에 대해 메서드를 호출합니다. 그래서 결과는 같으면서도 오류는 나오지 않게 되죠.

다음 예시에서는 Description이 ForEach-Object의 MemberName 파라미터에 전달돼요. 이 명령은 Get-Process가 반환한 각 System.Diagnostics.Process 객체의 설명을 화면에 표시합니다.

Get-Process | foreach Description

이번 예시에서는 메서드 이름 GetFiles가 ForEach-Object 명령의 MemberName 파라미터에 전달되고, .* 값이 ArgumentList 파라미터에 전달돼요. 그러면 Get-ChildItem이 반환한 각 System.IO.DirectoryInfo 객체에 대해, GetFiles() 메서드가 검색 패턴 파라미터 .*을 받아 호출됩니다.

Get-ChildItem /home -Directory | foreach GetFiles .*

더 알아보기