배열에 대해 알고 싶었던 모든 것

배열은 대부분의 프로그래밍 언어가 제공하는 기본적인 언어 기능입니다. 이 컬렉션은 피하기 어려운 값 또는 개체의 컬렉션입니다. 배열과 배열이 제공해야 하는 모든 것을 자세히 살펴보겠습니다.

참고 항목

현재 문서의 원본 버전@KevinMarquette가 작성한 블로그에 있습니다. PowerShell 팀은 이 콘텐츠를 공유해 주신 Kevin에게 감사드립니다. PowerShellExplained.com에 있는 그의 블로그를 확인하세요.

배열이란?

PowerShell에서 사용하는 다른 방법으로 전환하기 전에 배열이 무엇이고 대부분의 프로그래밍 언어에서 어떻게 사용되는지에 대한 기본 기술 설명부터 시작하겠습니다.

배열은 여러 항목의 컬렉션 역할을 하는 데이터 구조입니다. 배열 전체를 반복하거나 인덱스를 사용하여 개별 항목에 액세스할 수 있습니다. 배열은 각 값이 다른 값 바로 옆에 저장되는 순차적 메모리 청크로 만들어집니다.

나는 우리가 가서 그 세부 사항의 각각에 터치합니다.

기본 사용법

배열은 PowerShell의 기본 기능이므로 PowerShell에서 작업하기 위한 간단한 구문이 있습니다.

배열 만들기

빈 배열을 사용하여 만들 수 있습니다. @()

PS> $data = @()
PS> $data.count
0

배열을 만들고 괄호 안에 배치하여 값으로 시드할 @() 수 있습니다.

PS> $data = @('Zero','One','Two','Three')
PS> $data.count
4

PS> $data
Zero
One
Two
Three

이 배열에는 4개 항목이 있습니다. $data 변수를 호출하면 항목 목록이 표시됩니다. 문자열 배열인 경우 문자열당 한 줄을 가져옵니다.

여러 줄에 배열을 선언할 수도 있습니다. 이 경우 쉼표는 선택 사항이며 일반적으로 제외됩니다.

$data = @(
    'Zero'
    'One'
    'Two'
    'Three'
)

나는 그런 여러 줄에 내 배열을 선언하는 것을 선호합니다. 항목이 여러 대 있을 때 더 쉽게 읽을 수 있을 뿐만 아니라 소스 제어를 사용할 때 이전 버전과 더 쉽게 비교할 수 있습니다.

기타 구문

일반적으로 배열을 만드는 구문으로 이해 @() 되지만 쉼표로 구분된 목록은 대부분의 시간 동안 작동합니다.

$data = 'Zero','One','Two','Three'

배열을 만드는 쓰기 출력

아주 유용한 방법이 있는데 Write-Output을 사용하면 콘솔에서 문자열을 빠르게 만들 수 있다는 것입니다.

$data = Write-Output Zero One Two Three

매개 변수가 문자열을 허용한다면 문자열 주위에 따옴표를 붙일 필요가 없어 편리합니다. 나는 스크립트에서이 작업을 수행하지 않을 것이다하지만 콘솔에서 공정한 게임이다.

항목 액세스

이제 항목이 포함된 배열이 있으므로 해당 항목에 액세스하고 업데이트할 수 있습니다.

Offset

개별 항목에 액세스하려면 오프셋 값이 [] 0부터 시작하는 대괄호를 사용합니다. 배열의 첫 번째 항목을 가져오는 방법은 다음과 같습니다.

PS> $data = 'Zero','One','Two','Three'
PS> $data[0]
Zero

여기서 0을 사용하는 이유는 첫 번째 항목이 목록의 시작 부분에 있으므로 0개 항목의 오프셋을 사용하여 가져오기 때문입니다. 두 번째 항목으로 이동하려면 첫 번째 항목을 건너뛰려면 1의 오프셋을 사용해야 합니다.

PS> $data[1]
One

이것은 마지막 항목은 오프셋 3이라는 뜻입니다.

PS> $data[3]
Three

색인

이제 이 예제에서 내가 한 값을 선택한 이유를 확인할 수 있습니다. 실제로 오프셋이기 때문에 오프셋이라 소개했지만 일반적으로는 인덱스라고 합니다. 0에서 시작하는 인덱스입니다. 이 문서의 나머지 부분에서는 오프셋을 인덱스라고 하겠습니다.

특수 인덱스 기술

대부분의 언어에서는 단일 숫자만 인덱스로 지정할 수 있으며 단일 항목을 다시 가져올 수 있습니다. PowerShell은 훨씬 더 유연합니다. 여러 인덱스를 동시에 사용할 수 있습니다. 인덱스 목록을 제공하여 여러 항목을 선택할 수 있습니다.

PS> $data[0,2,3]
Zero
Two
Three

제공된 인덱스의 순서에 따라 항목이 반환됩니다. 인덱스가 중복되면 해당 항목을 두 번 모두 가져옵니다.

PS> $data[3,0,3]
Three
Zero
Three

기본 제공 연산자를 사용하여 숫자 시퀀스를 지정할 수 있습니다 .. .

PS> $data[1..3]
One
Two
Three

이것은 역으로도 작동합니다.

PS> $data[3..1]
Three
Two
One

음수 인덱스 값을 사용하여 끝에서 오프셋할 수 있습니다. 따라서 목록의 마지막 항목이 필요하다면 -1을 사용하면 됩니다.

PS> $data[-1]
Three

운영자와 함께 .. 여기에주의의 한 단어. 시퀀스 0..-1-1..00,-1 으로 계산합니다 -1,0. 이 사실을 잊으면 $data[0..-1]을 이용하고 이것이 모든 항목을 열거한다고 생각하기 쉽습니다. $data[0..-1] 는 배열의 첫 번째 항목과 마지막 항목을 제공하는 것과 $data[0,-1] 동일한 값을 제공합니다(다른 값은 없음). 다음은 더 큰 예제입니다.

PS> $a = 1,2,3,4,5,6,7,8
PS> $a[2..-1]
3
2
1
8

이는 다음과 같습니다.

PS> $a[2,1,0,-1]
3
2
1
8

범위를 벗어났습니다.

대부분의 언어에서 배열의 끝을 지난 항목의 인덱스에 액세스하려고 하면 일부 유형의 오류 또는 예외가 발생합니다. PowerShell은 아무 것도 자동으로 반환하지 않습니다.

PS> $null -eq $data[9000]
True

null 배열로 인덱싱할 수 없음

변수가 $null 배열처럼 인덱싱하려고 하면 메시지Cannot index into a null array와 함께 예외가 System.Management.Automation.RuntimeException 발생합니다.

PS> $empty = $null
PS> $empty[0]
Error: Cannot index into a null array.

따라서 배열 내부의 요소에 액세스하기 전에 배열이 없는지 $null 확인합니다.

Count

배열 및 기타 컬렉션에는 배열에 있는 항목 수를 알려주는 count 속성이 있습니다.

PS> $data.count
4

PowerShell 3.0은 대부분의 개체에 count 속성을 추가했습니다. 단일 개체를 가질 수 있으며 개수를 1제공해야 합니다.

PS> $date = Get-Date
PS> $date.count
1

반환0을 제외한 count 속성도 $null 있습니다.

PS> $null.count
0

이 문서의 뒷부분에서 배열에 대한 $null 검사 또는 빈 배열을 다룰 때 다시 방문할 몇 가지 트랩이 있습니다.

Off-by-One 오류

대표적인 프로그래밍 오류는 배열이 인덱스 0에서 시작되기 때문에 발생합니다. 오프 바이 원 오류는 두 가지 방법으로 도입 될 수 있습니다.

첫 번째는 정신적으로 두 번째 항목을 원한다고 생각하고 인덱 2 스 사용과 실제로 세 번째 항목을 가져오는 것입니다. 혹은 항목 4개가 있고 마지막 항목을 원하기 때문에 count를 이용해 마지막 항목에 액세스하는 경우도 있습니다.

$data[ $data.count ]

PowerShell을 사용하면 인덱스 4 $null에 있는 항목을 정확하게 제공할 수 있습니다. 위에서 배운 내용을 사용하거나 -1 사용해야 $data.count - 1 합니다.

PS> $data[ $data.count - 1 ]
Three

인덱스 -1 로 마지막 요소를 가져올 수 있습니다.

PS> $data[ -1 ]
Three

Lee Dailey는 또한 최대 인덱스 번호를 가져오는 데 사용할 $data.GetUpperBound(0) 수 있다고 지적했습니다.

PS> $data.GetUpperBound(0)
3
PS> $data[ $data.GetUpperBound(0) ]
Three

두 번째로 일반적인 방법은 목록을 반복하고 적절한 시간에 중지하지 않는 경우입니다. for 루프 사용을 다룰 때 자세히 설명하겠습니다.

항목 업데이트

동일한 인덱스로 배열의 기존 항목을 업데이트할 수 있습니다. 이 방법을 이용하면 직접 액세스하여 개별 항목을 업데이트할 수 있습니다.

$data[2] = 'dos'
$data[3] = 'tres'

마지막 요소를 지난 항목을 업데이트하려고 하면 오류가 발생합니다 Index was outside the bounds of the array. .

PS> $data[4] = 'four'
Index was outside the bounds of the array.
At line:1 char:1
+ $data[4] = 'four'
+ ~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (:) [], IndexOutOfRangeException
+ FullyQualifiedErrorId : System.IndexOutOfRangeException

나중에 배열을 더 크게 만드는 방법에 대해 이야기할 때 이를 다시 살펴보겠습니다.

반복

어떤 시점에서 전체 목록을 걷거나 반복하고 배열의 각 항목에 대해 몇 가지 작업을 수행해야 할 수 있습니다.

파이프라인

배열과 PowerShell 파이프라인은 서로를 위한 것입니다. 이러한 값을 처리하는 가장 간단한 방법 중 하나입니다. 배열을 파이프라인에 전달하면 배열 내의 각 항목이 개별적으로 처리됩니다.

PS> $data = 'Zero','One','Two','Three'
PS> $data | ForEach-Object {"Item: [$PSItem]"}
Item: [Zero]
Item: [One]
Item: [Two]
Item: [Three]

당신이 전에 본 $PSItem 적이 없는 경우, 그냥 같은 것을 $_알고 . 둘 다 파이프라인의 현재 개체를 나타내므로 둘 중 하나를 사용할 수 있습니다.

ForEach 루프

루프는 ForEach 컬렉션에서 잘 작동합니다. 구문 사용: foreach ( <variable> in <collection> )

foreach ( $node in $data )
{
    "Item: [$node]"
}

ForEach 메서드

나는이 것에 대해 잊어 버리는 경향이 있지만 간단한 작업에 잘 작동합니다. PowerShell을 사용하면 컬렉션을 호출 .ForEach() 할 수 있습니다.

PS> $data.foreach({"Item [$PSItem]"})
Item [Zero]
Item [One]
Item [Two]
Item [Three]

.foreach()는 스크립트 블록인 매개 변수를 사용합니다. 괄호를 삭제하고 스크립트 블록을 제공할 수 있습니다.

$data.foreach{"Item [$PSItem]"}

잘 알려지지 않은 구문이지만 효과는 동일합니다. 이 foreach 메서드는 PowerShell 4.0에서 추가되었습니다.

For 루프

루프 for 는 대부분의 다른 언어에서 많이 사용되지만 PowerShell에서는 많이 표시되지 않습니다. 당신이 그것을 볼 때, 그것은 종종 배열을 걷는 맥락에서.

for ( $index = 0; $index -lt $data.count; $index++)
{
    "Item: [{0}]" -f $data[$index]
}

가장 먼저 할 일은 0$index를 초기화하는 것입니다. 그런 다음 , 보다 $data.count작아야 하는 $index 조건을 추가합니다. 마지막으로, 루프할 때마다 인덱스 값을 늘 1여야 한다고 지정합니다. 이 경우 $index++$index = $index + 1의 축약형입니다. 형식 연산자(-f)는 출력 문자열의 $data[$index] 값을 삽입하는 데 사용됩니다.

루프를 for 사용할 때마다 조건에 특히 주의해야 합니다. 여기서는 $index -lt $data.count를 사용했습니다. 논리에서 일회용 오류를 발생시켜 조건을 약간 잘못 가져오는 것은 쉽습니다. 사용 $index -le $data.count 하거나 $index -lt ($data.count - 1) 너무 약간 잘못되었습니다. 너무 많거나 적은 항목을 처리한 결과가 발생하게 됩니다. 이것은 전형적인 OBO(off-by-one) 오류에 속합니다.

스위치 루프

이것은 간과하기 쉬운 항목입니다. switch 문에 배열을 제공하는 경우 배열의 각 항목을 검사.

$data = 'Zero','One','Two','Three'
switch( $data )
{
    'One'
    {
        'Tock'
    }
    'Three'
    {
        'Tock'
    }
    Default
    {
        'Tick'
    }
}
Tick
Tock
Tick
Tock

Switch 문을 이용하면 수많은 유용한 작업을 수행할 수 있습니다. 나는 이것에 전념하는 또 다른 기사가 있다.

값 업데이트

배열이 문자열 또는 정수(값 형식) 컬렉션이라면 루프할 때 배열의 값을 업데이트해야 할 때가 있습니다. 위의 루프 대부분은 값의 복사본을 보유하는 루프 내 변수를 사용합니다. 해당 변수를 업데이트하면 배열의 원래 값이 업데이트되지 않습니다.

해당 문의 예외는 루프입니다 for . 배열을 걷고 그 안에 for 값을 업데이트하려는 경우 루프가 원하는 것입니다.

for ( $index = 0; $index -lt $data.count; $index++ )
{
    $data[$index] = "Item: [{0}]" -f $data[$index]
}

이 예제에서는 인덱스별로 값을 가져와서 몇 가지 변경한 다음 동일한 인덱스로 다시 할당합니다.

개체 배열

지금까지 배열에 배치한 유일한 항목은 값 형식이지만 배열에는 개체도 포함될 수 있습니다.

$data = @(
    [pscustomobject]@{FirstName='Kevin';LastName='Marquette'}
    [pscustomobject]@{FirstName='John'; LastName='Doe'}
)

많은 cmdlet은 변수에 할당될 때 개체의 컬렉션을 배열로 반환합니다.

$processList = Get-Process

이미 설명한 모든 기본 기능은 몇 가지 세부 정보가 있는 개체 배열에 여전히 적용됩니다.

속성 액세스

인덱스로 값 형식과 마찬가지로 컬렉션의 개별 항목에 액세스할 수 있습니다.

PS> $data[0]

FirstName LastName
-----     ----
Kevin     Marquette

속성에 직접 액세스하고 업데이트할 수 있습니다.

PS> $data[0].FirstName

Kevin

PS> $data[0].FirstName = 'Jay'
PS> $data[0]

FirstName LastName
-----     ----
Jay       Marquette

배열 속성

일반적으로 모든 속성에 액세스하려면 다음과 같이 전체 목록을 열거해야 합니다.

PS> $data | ForEach-Object {$_.LastName}

Marquette
Doe

또는 Select-Object -ExpandProperty cmdlet을 사용해도 됩니다.

PS> $data | Select-Object -ExpandProperty LastName

Marquette
Doe

하지만 PowerShell은 LastName을 직접 요청하는 기능을 제공합니다. PowerShell은 모두 열거하고 클린 목록을 반환합니다.

PS> $data.LastName

Marquette
Doe

열거형은 여전히 발생하지만 그 뒤에 복잡성은 보이지 않습니다.

Where-Object 필터링

개체의 속성에 따라 배열에서 원하는 내용을 필터링하고 선택할 수 있도록 이 위치 Where-Object 가 제공됩니다.

PS> $data | Where-Object {$_.FirstName -eq 'Kevin'}

FirstName LastName
-----     ----
Kevin     Marquette

동일한 쿼리를 작성하여 찾고 있는 쿼리를 FirstName 가져올 수 있습니다.

$data | Where FirstName -eq Kevin

Where()

배열에는 필터의 scriptblock을 지정할 수 있는 Where() 메서드가 있습니다.

$data.Where({$_.FirstName -eq 'Kevin'})

이 기능은 PowerShell 4.0에 추가되었습니다.

루프에서 개체 업데이트

값 형식이 있는 배열을 업데이트하는 유일한 방법은 루프를 사용하는 것입니다. 값을 교체해야 하는 인덱스를 파악해야 하기 때문입니다. 개체는 참조 형식이므로 더 많은 선택지를 사용할 수 있습니다. 간단한 예제는 다음과 같습니다.

foreach($person in $data)
{
    $person.FirstName = 'Kevin'
}

이 루프는 배열의 모든 개체를 걷고 있습니다 $data . 개체는 참조 형식이므로 변수는 $person 배열에 있는 것과 정확히 동일한 개체를 참조합니다. 따라서 해당 속성에 대한 업데이트는 원본을 업데이트합니다.

여전히 전체 개체를 이런 식으로 바꿀 수는 없습니다. 변수에 새 개체를 $person 할당하려고 하면 변수 참조를 배열의 원래 개체를 더 이상 가리키지 않는 다른 개체로 업데이트합니다. 이 작업은 예상한 것처럼 작동하지 않습니다.

foreach($person in $data)
{
    $person = [pscustomobject]@{
        FirstName='Kevin'
        LastName='Marquette'
    }
}

연산자

PowerShell의 연산자도 배열에서 작동합니다. 일부 연산자는 작동 방식이 약간 다릅니다.

-가입

-join 연산자가 가장 확실한 연산자이므로 먼저 살펴보겠습니다. 나는 연산자를 -join 좋아하고 자주 사용합니다. 배열의 모든 요소를 지정한 문자 또는 문자열과 조인합니다.

PS> $data = @(1,2,3,4)
PS> $data -join '-'
1-2-3-4
PS> $data -join ','
1,2,3,4

연산자에 대해 -join 좋아하는 기능 중 하나는 단일 항목을 처리한다는 것입니다.

PS> 1 -join '-'
1

로깅 및 자세한 메시지 내에서 사용합니다.

PS> $data = @(1,2,3,4)
PS> "Data is $($data -join ',')."
Data is 1,2,3,4.

-join $array

리 데일리가 내게 지적한 영리한 트릭은 다음과 같습니다. 구분 기호 없이 모든 항목을 조인하려는 경우 다음을 수행하는 대신 다음을 수행합니다.

PS> $data = @(1,2,3,4)
PS> $data -join $null
1234

접두사 없이 배열을 매개 변수로 사용할 -join 수 있습니다. 이 예제를 살펴 보면 내가 말하는 것을 볼 수 있습니다.

PS> $data = @(1,2,3,4)
PS> -join $data
1234

-replace 및 -split

다른 연산자는 배열의 각 항목을 좋아 -replace 하고 -split 실행합니다. 나는 이런 식으로 그들을 사용한 적이 있다고 말할 수는 없지만 여기에 예가 있습니다.

PS> $data = @('ATX-SQL-01','ATX-SQL-02','ATX-SQL-03')
PS> $data -replace 'ATX','LAX'
LAX-SQL-01
LAX-SQL-02
LAX-SQL-03

포함-

-contains 연산자를 사용하면 값 배열을 검사 지정된 값이 포함되어 있는지 확인할 수 있습니다.

PS> $data = @('red','green','blue')
PS> $data -contains 'green'
True

-in

여러 값 중 하나와 일치하는지 확인하려는 단일 값이 있는 경우 연산자를 -in 사용할 수 있습니다. 값은 왼쪽에 있고 배열은 연산자의 오른쪽에 있습니다.

PS> $data = @('red','green','blue')
PS> 'green' -in $data
True

이 방법은 목록이 길다면 비용이 많이 들 수 있습니다. 몇 개 이상의 값을 검사 경우 종종 regex 패턴을 사용합니다.

PS> $data = @('red','green','blue')
PS> $pattern = "^({0})$" -f ($data -join '|')
PS> $pattern
^(red|green|blue)$

PS> 'green' -match $pattern
True

-eq 및 -ne

같음을 이용하면 배열이 복잡해질 수 있습니다. 배열이 왼쪽에 있으면 모든 항목이 비교됩니다. 반환하는 True대신 일치하는 개체를 반환합니다.

PS> $data = @('red','green','blue')
PS> $data -eq 'green'
green

-ne 연산자를 사용하면 대상 값과 같지 않은 모든 값을 가져옵니다.

PS> $data = @('red','green','blue')
PS> $data -ne 'green'
red
blue

문에서 if() 이 값을 사용하면 반환되는 값이 값입니다 True . 값이 반환되지 않으면 값입니다 False . 이 두 다음 문은 모두 .로 평가됩니다 True.

$data = @('red','green','blue')
if ( $data -eq 'green' )
{
    'Green was found'
}
if ( $data -ne 'green' )
{
    'And green was not found'
}

테스트에 대해 $null이야기할 때 잠시 후에 다시 살펴보겠습니다.

-match

연산자는 -match 컬렉션의 각 항목과 일치하려고 시도합니다.

PS> $servers = @(
    'LAX-SQL-01'
    'LAX-API-01'
    'ATX-SQL-01'
    'ATX-API-01'
)
PS> $servers -match 'SQL'
LAX-SQL-01
ATX-SQL-01

단일 값으로 -match를 사용하면 일치 정보에 특수 변수인 $Matches가 입력됩니다. 배열을 이 방식으로 처리할 때는 적용되지 않습니다.

을 사용하여 동일한 접근 방식을 Select-String취할 수 있습니다.

$servers | Select-String SQL

을 사용하는 다양한 방법이라는 게시물에서 Select-String,-match,$matches 변수를 자세히 살펴보겠습니다.

$null 또는 비어 있음

배열에 대한 $null 테스트 또는 빈 배열은 까다로울 수 있습니다. 다음을 배열에서 자주 발생하는 함정입니다.

이 문은 한눈에 작동해야 하는 것처럼 보입니다.

if ( $array -eq $null)
{
    'Array is $null'
}

그러나 배열의 각 항목을 검사 방법을 -eq 알아봤습니다. 따라서 단일 $null 값을 가진 여러 항목의 배열을 가질 수 있으며 $true

$array = @('one',$null,'three')
if ( $array -eq $null)
{
    'I think Array is $null, but I would be wrong'
}

이 때문에 연산자의 왼쪽에 배치 $null 하는 것이 가장 좋습니다. 이렇게 하면 이 시나리오는 문제가 되지 않습니다.

if ( $null -eq $array )
{
    'Array actually is $null'
}

배열은 $null 빈 배열과 동일하지 않습니다. 배열이 있다는 것을 알고 있는 경우 배열에 있는 개체 수를 검사. 배열이 $null면 개수는 .입니다 0.

if ( $array.count -gt 0 )
{
    "Array isn't empty"
}

여기에 주의해야 할 함정이 하나 더 있습니다. 단일 개체가 count 있는 경우에도 해당 개체가 없으면 이 개체를 사용할 수 있습니다 PSCustomObject. PowerShell 6.1에서 수정된 버그입니다. 반가운 소식이지만 아직 많은 사용자가 5.1을 사용하고 있으니 주의해야 합니다.

PS> $object = [PSCustomObject]@{Name='TestObject'}
PS> $object.count
$null

PowerShell 5.1을 계속 사용하는 경우 정확한 개수를 얻기 위해 개수를 검사 전에 배열에서 개체를 래핑할 수 있습니다.

if ( @($array).count -gt 0 )
{
    "Array isn't empty"
}

안전하게 재생하려면 검사 $null개수를 검사.

if ( $null -ne $array -and @($array).count -gt 0 )
{
    "Array isn't empty"
}

All -eq

최근에 배열의 모든 값이 지정된 값과 일치하는지 확인하는 방법을 묻는 사람이 있습니다. Reddit 사용자 /u/bis 님이 잘못된 값을 확인한 다음 결과를 대칭 이동하면 된다는 탁월한 해결책을 알려주었습니다.

$results = Test-Something
if ( -not ( $results -ne 'Passed') )
{
    'All results a Passed'
}

배열에 추가

이 시점에서 배열에 항목을 추가하는 방법을 궁금해하기 시작했습니다. 빠른 대답은 당신이 할 수 없다는 것입니다. 배열은 메모리의 고정 크기입니다. 확장하거나 단일 항목을 추가해야 하는 경우 새 배열을 만들고 이전 배열에서 모든 값을 복사해야 합니다. 이렇게 하면 작업량이 많을 것 같지만 PowerShell에서는 새 배열을 간단하게 만들 수 있습니다. PowerShell은 배열에 대한 더하기 연산자(+)를 구현합니다.

참고 항목

PowerShell은 빼기 작업을 구현하지 않습니다. 배열을 유연하게 대체하려면 제네릭 List 개체를 사용해야 합니다.

배열 추가

배열과 함께 더하기 연산자를 사용하여 새 배열을 만들 수 있습니다. 따라서 다음 두 배열을 지정합니다.

$first = @(
    'Zero'
    'One'
)
$second = @(
    'Two'
    'Three'
)

두 배열을 모두 추가하면 새 배열을 얻을 수 있습니다.

PS> $first + $second

Zero
One
Two
Three

Plus equals +=

새 배열을 만들고 다음과 같이 항목을 추가할 수 있습니다.

$data = @(
    'Zero'
    'One'
    'Two'
    'Three'
)
$data += 'four'

새 배열을 복제하고 만드는 것을 사용할 += 때마다 기억하세요. 이는 작은 데이터 세트에 문제가 되지 않지만 크기가 매우 극히 작습니다.

파이프라인 할당

파이프라인의 결과를 변수에 할당할 수 있습니다. 여러 항목이 포함된 경우 배열입니다.

$array = 1..5 | ForEach-Object {
    "ATX-SQL-$PSItem"
}

일반적으로 파이프라인 사용을 생각할 때 일반적인 PowerShell 한 라이너를 생각합니다. 문 및 기타 루프를 foreach() 사용하여 파이프라인을 활용할 수 있습니다. 따라서 여러 항목을 루프 내 배열에 추가하는 대신 파이프라인에 놓으면 됩니다.

$array = foreach ( $node in (1..5))
{
    "ATX-SQL-$node"
}

배열 형식

기본적으로 PowerShell의 배열은 [PSObject[]] 형식으로 생성됩니다. 이렇게 하면 모든 형식의 개체 또는 값을 포함할 수 있습니다. 이는 모든 항목이 형식에서 PSObject 상속되기 때문에 작동합니다.

강력한 형식의 배열

비슷한 구문을 사용하여 모든 형식의 배열을 만들 수 있습니다. 강력한 형식의 배열을 만들 때는 지정된 형식의 값이나 개체만 포함할 수 있습니다.

PS> [int[]] $numbers = 1,2,3
PS> [int[]] $numbers2 = 'one','two','three'
ERROR: Cannot convert value "one" to type "System.Int32". Input string was not in a correct format."

PS> [string[]] $strings = 'one','two','three'

ArrayList

배열에 항목을 추가하는 것은 가장 큰 제한 사항 중 하나이지만 이 문제를 해결할 수 있는 몇 가지 다른 컬렉션이 있습니다.

ArrayList는 빠르게 작동하는 배열을 만들 때 가장 먼저 떠올리는 요소입니다. 필요한 모든 위치에서 개체 배열처럼 작동하지만 항목 추가를 신속하게 처리합니다.

항목을 만들고 ArrayList 추가하는 방법은 다음과 같습니다.

$myarray = [System.Collections.ArrayList]::new()
[void]$myArray.Add('Value')

이 형식을 가져오기 위해 .NET을 호출합니다. 이 경우 기본 생성자를 사용하여 만듭니다. 그런 다음 Add 메서드를 호출하여 항목을 추가합니다.

줄의 시작 부분에서 사용하는 [void] 이유는 반환 코드를 표시하지 않는 것입니다. 일부 .NET 호출은 이 작업을 수행하며 예기치 않은 출력을 만들 수 있습니다.

배열에 있는 데이터가 문자열뿐이라면 StringBuilder 사용도 검토해봐야 합니다. 거의 동일하지만 문자열을 처리하기 위한 몇 가지 메서드가 있습니다. StringBuilder는 성능을 위해 특별히 설계되었습니다.

사람들이 배열에서 이동하는 ArrayList 것을 보는 것이 일반적입니다. 그러나 C#이 일반적인 지원을 받지 못했던 때에서 비롯되었습니다. 제 ArrayList 네릭에 대한 지원에서 더 이상 사용되지 않습니다. List[]

제네릭 목록

제네릭 형식은 일반화된 클래스를 정의하는 C#의 특수 형식이며 사용자가 만들 때 사용하는 데이터 형식을 지정합니다. 따라서 숫자 또는 문자열 목록을 원하는 경우 목록 int 또는 string 형식을 정의합니다.

문자열 목록을 만드는 방법은 다음과 같습니다.

$mylist = [System.Collections.Generic.List[string]]::new()

또는 숫자 목록입니다.

$mylist = [System.Collections.Generic.List[int]]::new()

먼저 개체를 만들지 않고 기존 배열을 다음과 같은 목록으로 캐스팅할 수 있습니다.

$mylist = [System.Collections.Generic.List[int]]@(1,2,3)

PowerShell 5 이상에서 문을 사용하여 using namespace 구문을 줄일 수 있습니다. using 문은 스크립트의 첫 번째 줄이어야 합니다. 네임스페이스를 선언하면 PowerShell을 사용하면 해당 네임스페이스를 참조할 때 데이터 형식에서 제외할 수 있습니다.

using namespace System.Collections.Generic
$myList = [List[int]]@(1,2,3)

이렇게 하면 List 훨씬 더 쉽게 사용할 수 있습니다.

비슷한 Add 메서드를 사용할 수도 있습니다. ArrayList와는 달리 Add 메서드에는 반환값이 없으므로 void하지 않아도 됩니다.

$myList.Add(10)

다른 배열 같은 요소에도 계속 액세스할 수 있습니다.

PS> $myList[-1]
10

List[PSObject]

모든 형식의 목록을 가질 수 있지만 개체의 형식을 모르는 경우 개체를 포함하는 데 사용할 [List[PSObject]] 수 있습니다.

$list = [List[PSObject]]::new()

Remove()

ArrayList 제네릭 List[] 은 모두 컬렉션에서 항목 제거를 지원합니다.

using namespace System.Collections.Generic
$myList = [List[string]]@('Zero','One','Two','Three')
[void]$myList.Remove("Two")
Zero
One
Three

값 형식을 사용할 때 목록에서 첫 번째 값을 제거합니다. 이 값을 계속 제거하려면 반복해서 호출할 수 있습니다. 참조 형식이 있는 경우 제거할 개체를 제공해야 합니다.

[list[System.Management.Automation.PSDriveInfo]]$drives = Get-PSDrive
$drives.remove($drives[2])
$delete = $drives[2]
$drives.remove($delete)

remove 메서드는 컬렉션에서 항목을 찾아 제거할 수 있으면 반환 true 합니다.

추가 컬렉션

다른 많은 컬렉션을 사용할 수 있지만 바람직한 일반 배열 대체는 다음과 같습니다. 이러한 옵션에 대해 자세히 알아보려면 Mark Kraus함께 사용한 이 시스트를 살펴보세요.

기타 뉘앙스

이제 모든 주요 기능을 다루었으므로 이 작업을 마무리하기 전에 멘션 몇 가지 사항을 추가했습니다.

미리 크기가 조정된 배열

배열을 만든 후에는 배열의 크기를 변경할 수 없다는 멘션. new($size) 생성자로 호출하면 미리 정한 크기의 배열을 만들 수 있습니다.

$data = [Object[]]::new(4)
$data.count
4

배열 곱하기

흥미로운 작은 비결은 배열을 정수로 곱할 수 있다는 것입니다.

PS> $data = @('red','green','blue')
PS> $data * 3
red
green
blue
red
green
blue
red
green
blue

0으로 초기화

일반적인 시나리오는 모든 0이 있는 배열을 만들려고 하는 것입니다. 정수만 있는 경우 강력한 형식의 정수 배열은 기본적으로 모든 0으로 설정됩니다.

PS> [int[]]::new(4)
0
0
0
0

곱하기 기법을 이용하여 이 작업을 할 수도 있습니다.

PS> $data = @(0) * 4
PS> $data
0
0
0
0

곱하기 트릭에 대한 좋은 점은 당신이 어떤 값을 사용할 수 있다는 것입니다. 따라서 기본값으로 사용 255 하려는 경우 이 작업을 수행하는 것이 좋습니다.

PS> $data = @(255) * 4
PS> $data
255
255
255
255

중첩된 배열

배열 내의 배열을 중첩된 배열이라고 합니다. PowerShell에서는 이러한 기능을 많이 사용하지 않지만 다른 언어로 더 많이 사용했습니다. 데이터가 패턴과 같은 그리드에 맞는 경우 배열 배열을 사용하는 것이 좋습니다.

다음은 2차원 배열을 만들 수 있는 두 가지 방법입니다.

$data = @(@(1,2,3),@(4,5,6),@(7,8,9))

$data2 = @(
    @(1,2,3),
    @(4,5,6),
    @(7,8,9)
)

이러한 예제에서는 쉼표가 대단히 중요합니다. 쉼표가 선택 사항인 여러 줄에서 일반 배열의 이전 예제를 제공했습니다. 다차원 배열의 경우는 그렇지 않습니다.

인덱스 표기법을 사용하는 방식은 이제 중첩된 배열이 있으므로 약간 변경됩니다. 위의 값을 $data 사용하여 값 3에 액세스하는 방법입니다.

PS> $outside = 0
PS> $inside = 2
PS> $data[$outside][$inside]
3

배열 중첩의 각 수준에 대괄호 집합을 추가합니다. 첫 번째 대괄호 집합은 가장 바깥쪽 배열에 사용하며 이곳에서 작업을 수행합니다.

Write-Output -NoEnumerate

PowerShell은 배열의 래프 해제 또는 열거를 좋아합니다. 이는 PowerShell에서 파이프라인을 사용하는 방식의 핵심 측면이지만 이러한 문제가 발생하지 않도록 하려는 경우가 있습니다.

자세한 정보를 확인하고자 자주 개체를 Get-Member에 연결합니다. 배열을 파이프하면 래핑이 해제되고 Get-Member는 실제 배열이 아닌 배열의 멤버를 확인합니다.

PS> $data = @('red','green','blue')
PS> $data | Get-Member
TypeName: System.String
...

배열 Write-Output -NoEnumerate의 래프 해제를 방지하려면 .

PS> Write-Output -NoEnumerate $data | Get-Member
TypeName: System.Object[]
...

나는 해킹의 더 많은 두 번째 방법을 가지고 (나는이 같은 해킹을 피하기 위해 노력). 쉼표는 파이프하기 전에 배열 앞에 배치할 수 있습니다. 이는 유일한 요소인 다른 배열로 래핑 $data 되므로 외부 배열의 래핑을 해제한 후 래 $data 핑 해제됩니다.

PS> ,$data | Get-Member
TypeName: System.Object[]
...

배열 반환

이러한 배열 래핑 해제는 함수에서 값을 출력하거나 반환할 때도 발생합니다. 일반적으로 문제가 되지 않도록 변수에 출력을 할당하는 경우에도 배열을 가져올 수 있습니다.

캐치는 새 배열이 있다는 것입니다. 문제가 있는 경우 사용 Write-Output -NoEnumerate $array 하거나 return ,$array 해결할 수 있습니다.

다른 내용을 알고 싶으신가요?

습득하기엔 많은 내용이라는 걸 잘 압니다. 내 희망은 당신이 그것을 읽을 때마다이 문서에서 뭔가를 배우고 그것은 앞으로 오랜 시간 동안 당신을위한 좋은 참조로 판명되는 것입니다. 도움이 된다면 가치를 얻을 수 있다고 생각하는 다른 사용자와 공유하세요.

여기에서 해시 테이블에 대해 쓴 유사한 게시물을 검사 것이 좋습니다.