Powershell에서 Null 병합
powershell에 null 병합 연산자가 있습니까?
powershell에서 다음 C # 명령을 수행 할 수 있기를 바랍니다.
var s = myval ?? "new value";
var x = myval == null ? "" : otherval;
Powershell Community Extensions가 필요하지 않습니다. 표준 Powershell if 문을 표현식으로 사용할 수 있습니다.
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에는 실제 Null 병합 연산자 또는 최소한 이러한 동작을 수행 할 수있는 연산자가 있습니다. 그 연산자는 -ne
다음과 같습니다.
# Format:
# ($a, $b, $c -ne $null)[0]
($null, 'alpha', 1 -ne $null)[0]
# Output:
alpha
It's a bit more versatile than a null coalescing operator, since it makes an array of all non-null items:
$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
works similarly, which is useful for counting null entries:
($null, 'a', $null -eq $null).Length
# Result:
2
But anyway, here's a typical case to mirror C#'s ??
operator:
'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Output
Explanation
This explanation is based on an edit suggestion from an anonymous user. Thanks, whoever you are!
Based on the order of operations, this works in following order:
- The
,
operator creates an array of values to be tested. - The
-ne
operator filters out any items from the array that match the specified value--in this case, null. The result is an array of non-null values in the same order as the array created in Step 1. [0]
is used to select the first element of the filtered array.
Simplifying that:
- Create an array of possible values, in preferred order
- Exclude all null values from the array
- Take the first item from the resulting array
Caveats
Unlike C#'s null coalescing operator, every possible expression will be evaluated, since the first step is to create an array.
This is only half an answer to the first half of the question, so a quarter answer if you will, but there is a much simpler alternative to the null coalescing operator provided the default value you want to use is actually the default value for the type:
string s = myval ?? "";
Can be written in Powershell as:
([string]myval)
Or
int d = myval ?? 0;
translates to Powershell:
([int]myval)
I found the first of these useful when processing an xml element that might not exist and which if it did exist might have unwanted whitespace round it:
$name = ([string]$row.td[0]).Trim()
The cast to string protects against the element being null and prevents any risk of Trim()
failing.
If you install the Powershell Community Extensions Module then you can use:
?? is the alias for Invoke-NullCoalescing.
$s = ?? {$myval} {"New Value"}
?: is the alias for Invoke-Ternary.
$x = ?: {$myval -eq $null} {""} {$otherval}
$null, $null, 3 | Select -First 1
returns
3
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]
}
Often I find that I also need to treat empty string as null when using coalesce. I ended up writing a function for this, which uses Zenexer's solution for coalescing for the simple null coalesce, and then used Keith Hill's for null or empty checking, and added that as a flag so my function could do both.
One of the advantages of this function is, that it also handles having all elements null (or empty), without throwing an exception. It can also be used for arbitrary many input variables, thanks to how PowerShell handles array inputs.
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)
}
}
This produces the following test results:
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
Test code:
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)
Closest I can get is: $Val = $MyVal |?? "Default Value"
I implemented the null coalescing operator for the above like this:
function NullCoalesc {
param (
[Parameter(ValueFromPipeline=$true)]$Value,
[Parameter(Position=0)]$Default
)
if ($Value) { $Value } else { $Default }
}
Set-Alias -Name "??" -Value NullCoalesc
The conditional ternary operator could be implemented in a similary way.
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
And used like: $Val = $MyVal |?: $MyVal "Default Value"
참고URL : https://stackoverflow.com/questions/10623907/null-coalescing-in-powershell
'developer tip' 카테고리의 다른 글
날짜 문자열 구문 분석 및 형식 변경 (0) | 2020.08.26 |
---|---|
Node.js의 동기 요청 (0) | 2020.08.26 |
nltk 또는 python을 사용하여 불용어를 제거하는 방법 (0) | 2020.08.26 |
"java.security.cert.CertificateException : 제목 대체 이름 없음"오류를 수정하는 방법은 무엇입니까? (0) | 2020.08.26 |
SmtpException : 전송 연결에서 데이터를 읽을 수 없음 : net_io_connectionclosed (0) | 2020.08.26 |