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


33

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은 배열을 다루거나하지 않습니다.

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


StackOverflow의에서이 도움이 될 수 있습니다 : stackoverflow.com/questions/1827862/...의 stackoverflow.com/questions/1390782/...을 당신이 파이프되지 않은 경우 $_.Contains, 다음 %{,,$_.Name}작동합니다 ...

답변:


56

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

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

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

당신은 할 수 없습니다.

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

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

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

고마워, 이건 완벽 해! 15 개의 평판을 얻 자마자 투표합니다.
cheesus SO는 Monica에게 해를 끼치 지 않습니다.

2
"강제"할 수 있는지 확실하지 않습니다. @(1) | ConvertTo-Json여전히 1대신에를 반환 합니다 [1].
Marc

@Marc : ConvertTo-Json컬렉션을 반환하지 않습니다. 전체 입력을 읽고 단일 문자열로 변환합니다. 입력 개체를 개별적으로 변환하려면 각각 개별적으로 처리해야합니다.
Richard

1
@Richard, 나는 당신이 오해한다고 생각한다. 나는 다른 많은 사람들이 기본적으로 전체 객체 (예 : 컬렉션)를 직렬화하기를 원한다 (예 : 외부 지속성을 위해). 컬렉션의 각 객체를 개별적으로 처리하는 데 관심이 없습니다. ConvertTo-Json은 빈 배열 / 컬렉션이더라도 원본 객체를 반환하는 문자열을 반환해야합니다.
Marc

@Marc이 질문의 요점은 단일 요소 배열이 해당 요소로 취급되는 것을 피하는 것입니다 (이는 PSH 변경으로 인한 문제가 적습니다 : 질문 날짜 참고). 당신은 완전히 다른 경우에 대해 이야기하고 있습니다 (컬렉션을 단일 객체로 강제 함).
Richard

2

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

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

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

PS> ls *og*

6
Shay , 아직 답변에 댓글을 달 수 없지만 귀하의 진술은 사실이 아닙니다. PowerShell은 여전히 ​​요소를 상자에 넣지 만, 단일 항목에 "수"값을 지정한대로 표시합니다. 그러나 단일 항목 결과는 여전히 상자에 표시되지 않습니다. PS 3에 대해 위의 예를 테스트하고 결과를 볼 수 있습니다.
Tohuw

1
PS 5에서도 동작은 동일합니다.
MEMark

그래, 데프는 여전히 존재
제임스 Wiseman

1
이 동작은 PS 6.0.1에서도 동일합니다
spuder

2

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

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

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.