Powershell이 ​​하나의 항목이있는 문자열 배열을 문자열로 자동 변환하는 이유 _. Name}

C : \에서 이름에 ‘og’가있는 폴더를 검색하는 다음 Powershell 스크립트를 고려하십시오.

PS C : \> (ls | % {$ _. Name} |? {$ _. 포함 ( "og")})
성능 로그
프로그램 파일
setup.log

이제 검색 범위를 좁혀 하나의 항목 만 얻습니다.

PS C : \> (ls | % {$ _. Name} |? {$ _. Contains ( "Prog")})
프로그램 파일

이상한 것은 첫 번째 연산이 배열을 생성하는 반면, 두 번째 연산 (의미 적으로 동일한 연산이므로 동일한 유형의 결과를 생성해야 함)은 문자열을 생성한다는 것 입니다. 이것은 다음 결과에서 볼 수 있습니다.

PS C : \> (ls | % {$ _. Name} |? {$ _. 포함 ( "og")}). 길이
삼
PS C : \> (ls | % {$ _. Name} |? {$ _. 포함 ( "Prog")}). 길이
13

‘Prog’와 일치하는 폴더보다 ‘og’와 일치하는 폴더가 적기 때문에 이것은 매우 자극적입니다.

분명히 PowerShell은 단일 항목 배열을 단일 개체에 암시 적으로 ‘개봉’하고 길이가 1 인 배열을 얻지 못합니다. 파이프 라인에서 오는 결과를 계산할 때마다 파이프 라인을 통해 오는 결과를 계산할 때마다 m은 배열을 다루거나하지 않습니다.

이 문제가 발생하지 않도록하려면 어떻게해야합니까? 이것을 어떻게 처리합니까?



답변

분명히 PowerShell은 단일 항목 배열을 단일 개체에 암시 적으로 ‘개봉’합니다.

그리고 0의 항목 결과는 $null입니다.

이 문제가 발생하지 않도록하려면 어떻게해야합니까?

당신은 할 수 없습니다.

이것을 어떻게 처리합니까?

배열 생성자 ( @(...))를 사용하여 컬렉션을 강제로 (아무도 0 또는 하나의 요소로) 반환 할 수 있습니다.

$res = @(ls | %{$_.Name} | ?{$_.Contains("Prog")})

답변

이것은 PowerShell v3에서 해결되었습니다.

http://blogs.microsoft.co.il/blogs/scriptfanatic/archive/2012/03/19/Counting-objects-in-PowerShell-3.0.aspx

참고로 와일드 카드를 사용하여 이름에 무언가가 포함되어 있는지 확인할 수 있습니다.

PS> ls *og*

답변

이 두 결과의 차이점에 유의하십시오.

PS C:\> ConvertTo-Json -InputObject @(1)
[
    1
]
PS C:\> @(1)|ConvertTo-Json
1
PS C:\>

요점은 파이프 작업으로 ‘unboxing’을 수행한다는 것입니다. ConvertTo-Json은 파이프 대신 InputObject를 사용하면 객체를 배열로 간주합니다.