programing

powershell의 Null 병합

mbctv 2023. 4. 16. 15:37
반응형

powershell의 Null 병합

powershell에 null 통합 연산자가 있습니까?

다음 c# 명령어를 powershell로 실행할 수 있으면 좋겠습니다.

var s = myval ?? "new value";
var x = myval == null ? "" : otherval;

Powershell 7 이상

Powershell 7은 네이티브 늘 병합, 늘 조건부 할당 및 3진 연산자를 Powershell에 도입했습니다.

특수한 병합

$null ?? 100    # Result is 100

"Evaluated" ?? (Expensive-Operation "Not Evaluated")    # Right side here is not evaluated

특수한 조건부 할당

$x = $null
$x ??= 100    # $x is now 100
$x ??= 200    # $x remains 100

삼진 연산자

$true  ? "this value returned" : "this expression not evaluated"
$false ? "this expression not evaluated" : "this value returned"

이전 버전:

Powershell Community Extensions는 필요 없습니다.다음 문장으로 표현하면 표준 Powershell을 사용할 수 있습니다.

variable = if (condition) { expr1 } else { expr2 }

첫 번째 C# 표현에 대한 대체품:

var s = myval ?? "new value";

는 다음 중 하나가 됩니다(프리퍼런스에 따라 다름).

$s = if ($myval -eq $null) { "new value" } else { $myval }
$s = if ($myval -ne $null) { $myval } else { "new value" }

또는 사용할 수 있는 $myval에 따라 달라집니다.

$s = if ($myval) { $myval } else { "new value" }

두 번째 C# 표현도 같은 방법으로 매핑됩니다.

var x = myval == null ? "" : otherval;

된다

$x = if ($myval -eq $null) { "" } else { $otherval }

공정하게 말하면, 이것들은 그다지 재빠르지 않고, C# 폼만큼 사용하기 편하지도 않습니다.

또한 내용을 읽기 쉽게 하기 위해 매우 간단한 기능으로 래핑하는 것도 고려할 수 있습니다.

function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } }

$s = Coalesce $myval "new value"

또는 IfNull:

function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } }

$s = IfNull $myval "new value" $myval
$x = IfNull $myval "" $otherval

보시다시피 매우 간단한 함수로 구문의 자유를 상당히 얻을 수 있습니다.

업데이트: 혼재 시 고려해야 할 추가 옵션 중 하나는 보다 일반적인 IsTrue 함수입니다.

function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } }

$x = IfTrue ($myval -eq $null) "" $otherval

그리고 이것이 Powershell의 연산자처럼 보이는 에일리어스를 선언하는 기능입니다.결국 다음과 같습니다.

New-Alias "??" Coalesce

$s = ?? $myval "new value"

New-Alias "?:" IfTrue

$ans = ?: ($q -eq "meaning of life") 42 $otherval

모든 사람의 취향에 맞는 것은 아니지만, 당신이 찾고 있는 것이기도 합니다.

Thomas가 지적한 바와 같이 C# 버전과 위의 다른 미묘한 차이점은 C#이 인수를 단락시키지만 함수/에일리어스를 포함하는 Powershell 버전은 항상 모든 인수를 평가한다는 것입니다.는, 「」를 .if표현 형식

PowerShell 7 이후

PowerShell 7은 많은 신기능을 도입하여 에서 이행합니다.에 NET Framework를 설정합니다.NET 코어2020년 중반 현재 PowerShell의 레거시 버전을 완전히 대체하지 못하고 있습니다.이는 에 의존하기 때문입니다.그러나 Microsoft는 Core 패밀리가 종래의 프레임워크 패밀리를 대체할 것을 요구하고 있습니다.이 문서를 읽을 때까지 호환되는 버전의 PowerShell이 시스템에 미리 설치되어 있을 수 있습니다. 그렇지 않은 경우 https://github.com/powershell/powershell을 참조하십시오.

설명서에 따르면 PowerShell 7.0에서는 다음 연산자가 즉시 지원됩니다.

  1. Null-Coalesing:??
  2. Null 병합 할당:??=
  3. 삼진법:... ? ... : ...

이들은 늘 머지 시 예상되는 대로 동작합니다.

$x = $a ?? $b ?? $c ?? 'default value'
$y ??= 'default value'

3진 연산자가 도입되었기 때문에 null 병합 연산자를 추가할 필요가 없지만 다음 사항이 가능합니다.

$x = $a -eq $null ? $b : $a

7.0 에서는, 다음의 것도 사용할 수 있습니다.PSNullConditionalOperatorsdocs(1, 2)에서 설명하듯이 옵션 기능은 유효합니다.

  1. 멤버에늘: " " " " " null " " " :?.
  2. :?[]

여기에는 몇 가지 주의사항이 있습니다.

  1. 이것들은 실험적인 것이기 때문에 변경될 수 있습니다.이 문서를 읽을 때까지 더 이상 실험적인 것으로 간주되지 않을 수 있으며 경고 목록이 변경되었을 수 있습니다.
  2. 는 be음음음음음 be variables variables 、 '다'로 .${}변수 이름에는 물음표가 허용되므로 실험 연산자 중 하나가 뒤에 오는 경우.기능이 실험 상태에서 졸업하는 경우(호 11379 참조)에 이 문제가 발생할지는 불분명합니다.예를들면,${x}?.Test()연산자를 하지만, 「」는 「」입니다.$x?.Test()Test()「」라고 하는 $x?.
  3. ?(TypeScript는 TypeScript를 사용합니다.하지 않습니다.$x.Test?()

PowerShell 6 이전 버전

PowerShell 7 이전 버전에는 실제 null 병합 연산자 또는 적어도 이러한 동작을 수행할 수 있는 연산자가 있습니다. 는 ★★★★★★★★★★★★★★★★★★.-ne:

# Format:
# ($a, $b, $c -ne $null)[0]
($null, 'alpha', 1 -ne $null)[0]

# Output:
alpha

Null이 아닌 모든 항목의 배열을 만들기 때문에 Null 병합 연산자보다 약간 더 다용도입니다.

$items = $null, 'alpha', 5, 0, '', @(), $null, $true, $false
$instances = $items -ne $null
[string]::Join(', ', ($instances | ForEach-Object -Process { $_.GetType() }))

# Result:
System.String, System.Int32, System.Int32, System.String, System.Object[],
System.Boolean, System.Boolean

-eq마찬가지로 늘엔트리를 셀 때합니다.

($null, 'a', $null -eq $null).Length

# Result:
2

의 C#을 본뜬 .??★★★★★★★★★★★★★★★★★★:

'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Output

설명.

이 설명은 익명 사용자의 편집 제안에 기초하고 있습니다.고마워요, 당신이 누구든!

조작 순서에 근거해, 다음의 순서로 동작합니다.

  1. ,연산자는 테스트할 값의 배열을 만듭니다.
  2. -ne는의 모든 이 경우 null.dl은 null.dl로 있습니다. 과 같은 로 늘 의 값이 됩니다.
  3. [0]필터링된 배열의 첫 번째 요소를 선택하는 데 사용됩니다.

심플화:

  1. 원하는 순서대로 가능한 값의 배열을 만듭니다.
  2. 어레이에서 모든 null 값 제외
  3. 결과 배열에서 첫 번째 항목을 가져옵니다.

주의사항

C#의 null marge 연산자와 달리 첫 번째 단계는 어레이를 작성하는 것이기 때문에 가능한 모든 식을 평가합니다.

이는 질문의 첫 번째 절반에 대한 답변에 불과하므로 분기별로 답변해 주십시오.단, 사용하는 기본값이 실제로 유형의 기본값인 경우 null marge 연산자를 대체하는 훨씬 간단한 방법이 있습니다.

string s = myval ?? "";

Powershell에서는 다음과 같이 기술할 수 있습니다.

([string]myval)

또는

int d = myval ?? 0;

Powershell로 변환됩니다.

([int]myval)

존재하지 않을 수 있는 xml 요소를 처리할 때 다음 중 첫 번째 요소가 유용하다는 것을 알게 되었습니다. xml 요소가 존재한다면 해당 요소 주위에 불필요한 공백이 있을 수 있습니다.

$name = ([string]$row.td[0]).Trim()

문자열에 대한 캐스트는 요소가 null이 되지 않도록 보호하고 다음 위험을 방지합니다.Trim()실패.

$null, $null, 3 | Select -First 1

돌아온다

3

Powershell 커뮤니티 확장 모듈을 설치하면 다음을 사용할 수 있습니다.

? ?는 Invoke-Null Coalescing의 에일리어스입니다.

$s = ?? {$myval}  {"New Value"}

?: Invoke-Ternary 에일리어스입니다.

$x = ?: {$myval -eq $null} {""} {$otherval}

마지막으로 PowerShell 7에 Null 병합 할당 연산자가 추가되었습니다.

PS > $null ?? "a"
a
PS > "x" ?? "y"
x
PS > $x = $null
PS > $x ??= "abc"
PS > $x
abc
PS > $x ??= "xyz"
PS > $x
abc
function coalesce {
   Param ([string[]]$list)
   #$default = $list[-1]
   $coalesced = ($list -ne $null)
   $coalesced[0]
 }
 function coalesce_empty { #COALESCE for empty_strings

   Param ([string[]]$list)
   #$default = $list[-1]
   $coalesced = (($list -ne $null) -ne '')[0]
   $coalesced[0]
 }
@($null,$null,"val1","val2",5) | select -First 1

병합을 사용할 때 빈 문자열도 늘로 취급해야 하는 경우가 종종 있습니다.이 함수를 작성하게 되었습니다.이 함수는 단순한 늘 결합을 위한 결합에 제넥서 솔루션을 사용하고, 늘 또는 빈 체크에 키스 힐의 솔루션을 사용하고, 그것을 플래그로 추가함으로써 두 가지 기능을 모두 수행할 수 있게 되었습니다.

이 함수의 장점 중 하나는 예외 없이 모든 요소가 null(또는 비어 있음)인 것도 처리할 수 있다는 것입니다.또한 PowerShell이 어레이 입력을 처리하는 방식 덕분에 임의의 여러 입력 변수에도 사용할 수 있습니다.

function Coalesce([string[]] $StringsToLookThrough, [switch]$EmptyStringAsNull) {
  if ($EmptyStringAsNull.IsPresent) {
    return ($StringsToLookThrough | Where-Object { $_ } | Select-Object -first 1)
  } else {
    return (($StringsToLookThrough -ne $null) | Select-Object -first 1)
  }  
}

이를 통해 다음과 같은 테스트 결과가 생성됩니다.

Null coallesce tests:
1 (w/o flag)  - empty/null/'end'                 : 
1 (with flag) - empty/null/'end'                 : end
2 (w/o flag)  - empty/null                       : 
2 (with flag) - empty/null                       : 
3 (w/o flag)  - empty/null/$false/'end'          : 
3 (with flag) - empty/null/$false/'end'          : False
4 (w/o flag)  - empty/null/"$false"/'end'        : 
4 (with flag) - empty/null/"$false"/'end'        : False
5 (w/o flag)  - empty/'false'/null/"$false"/'end': 
5 (with flag) - empty/'false'/null/"$false"/'end': false

테스트 코드:

Write-Host "Null coalesce tests:"
Write-Host "1 (w/o flag)  - empty/null/'end'                 :" (Coalesce '', $null, 'end')
Write-Host "1 (with flag) - empty/null/'end'                 :" (Coalesce '', $null, 'end' -EmptyStringAsNull)
Write-Host "2 (w/o flag)  - empty/null                       :" (Coalesce('', $null))
Write-Host "2 (with flag) - empty/null                       :" (Coalesce('', $null) -EmptyStringAsNull)
Write-Host "3 (w/o flag)  - empty/null/`$false/'end'          :" (Coalesce '', $null, $false, 'end')
Write-Host "3 (with flag) - empty/null/`$false/'end'          :" (Coalesce '', $null, $false, 'end' -EmptyStringAsNull)
Write-Host "4 (w/o flag)  - empty/null/`"`$false`"/'end'        :" (Coalesce '', $null, "$false", 'end')
Write-Host "4 (with flag) - empty/null/`"`$false`"/'end'        :" (Coalesce '', $null, "$false", 'end' -EmptyStringAsNull)
Write-Host "5 (w/o flag)  - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end')
Write-Host "5 (with flag) - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end' -EmptyStringAsNull)

내가 얻을 수 있는 가장 가까운 것은:$Val = $MyVal |?? "Default Value"

위의 null margeing 연산자를 다음과 같이 구현했습니다.

function NullCoalesc {
    param (
        [Parameter(ValueFromPipeline=$true)]$Value,
        [Parameter(Position=0)]$Default
    )

    if ($Value) { $Value } else { $Default }
}

Set-Alias -Name "??" -Value NullCoalesc

조건부 3진 연산자는 유사한 방법으로 구현될 수 있다.

function ConditionalTernary {
    param (
        [Parameter(ValueFromPipeline=$true)]$Value,
        [Parameter(Position=0)]$First,
        [Parameter(Position=1)]$Second
    )

    if ($Value) { $First } else { $Second }
}

Set-Alias -Name "?:" -Value ConditionalTernary

사용방법:$Val = $MyVal |?: $MyVal "Default Value"

저도 비슷한 문제가 있었는데...

존재하지 않는 어레이 인덱스를 취급하는 경우는, 심플화하기가 매우 어려웠습니다.

또는 아직 정의/작성되지 않은 다른 변수에서 할당하려는 경우(단, Powershell에서는 발생할 수 있음) 더 이상할 수 있습니다.

예:

    $x = $y         # and $y id not defined/created yet
       -or-
    $x = $args[2]   # and args has less than 3 elements

이상하게도 몇 가지 대안을 생각해 봤는데, 그 중 하나가 매우 편리해졌어요.
가 합니다.
다음 소비자를 위해 파이프에 남아 있는 '표본화된' 스택 값...

so this works flawlessly:
    $x = try{ $y }      catch { 1 }    # $x becomes 1
    $x = try{ $a[ 2 ] } catch { 2 }    #$ x becomes 2
    $x = try{ $a[ 2 ] } catch {   }    #$ x becomes $null
  • 내게는 많은 암호를 단순화시켰어
  • 옵션 파라미터의 고도의 처리도 지원*

도움이 되길 바래!

Powershell 6 이전 버전에서는 본질적으로 단락되지 않는 함수를 사용합니다., 두 값만 허용하며 조건을 평가하기 전에 양쪽을 무조건 평가합니다.

할 수 .ScriptBlock.도..., 이...로 수 InputObject에 .

function ?? {
    param (
        [Parameter(ValueFromPipeline)]
        $InputObject,

        [Parameter(Mandatory, Position=1)]
        [ScriptBlock]
        $If,

        [Parameter(Position=2)]
        [ScriptBlock]
        $Else
    )
    if ($PSBoundParameters.ContainsKey("Else")) {
        if ($InputObject) {
            return (Invoke-Command $If);
        }
        return (Invoke-Command $Else);
    }
    else {
        if ($InputObject -ne $null) {
            return $InputObject;
        }
        return (Invoke-Command $If);
    }
}

이렇게 쓰는 거예요.

$s = $myval | ?? { "new value" };
$x = $myval | ?? { "" } { $otherval };

파워셸 7만큼 재빠르진 않지만 몇 명의 캐릭터만 남았습니다.

다음의 점에 주의해 주세요.

  • 예에서는 이 .$myval -eq null$myval에.if파워셸
  • 입력 파라미터는 파이프라인에서 송신됩니다.ScriptBlock파라미터가 위치하기 때문에 장황함을 줄일 수 있습니다.

비슷한 옵션은 SQL과 비슷하며 다음과 같은 어레이를 사용할 수 있습니다.ScriptBlock첫 번째 비반복 결과가 반환됩니다.

function Coalesce {
    param (
        [Parameter(Mandatory, Position=0)]
        [ScriptBlock[]]
        $Scripts
    )
    return (
        $Scripts |
        % { Invoke-Command $_ } |
        where { $_ } |
        select -First 1);
}

이렇게 쓸 수 있어요.

$x = Coalesce {Some-Calculation},{Other-Function};

:select -First 1첫 번째 결과 할 수 있을 또, 「」는 「반복」이라고 하는 것입니다.% ★★★★★★★★★★★★★★★★★」where이치노

언급URL : https://stackoverflow.com/questions/10623907/null-coalescing-in-powershell

반응형