当前位置: 首页 > 知识库问答 >
问题:

powershell中的空合并

史淳
2023-03-14

powershell中是否有空合并运算符?

我希望能够在powershell中执行以下c#命令:

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

共有3个答案

羊舌源
2023-03-14

这只是问题前半部分的一半答案,因此如果愿意的话,可以给出四分之一的答案,但如果要使用的默认值实际上是该类型的默认值,则有一种比空合并运算符更简单的替代方法:

string s = myval ?? "";

可以在Powershell中编写为:

([string]myval)

或者

int d = myval ?? 0;

转换为Powershell:

([int]myval)

我发现第一个在处理可能不存在的xml元素时很有用,如果它确实存在,它周围可能有不需要的空白:

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

转换为字符串可防止元素为空并防止Trim()失败的任何风险。

宗政金鹏
2023-03-14

PowerShell 7引入了许多新功能并从. NET Framework迁移到. NET Core。截至2020年年中,由于对. NET Core的依赖,它还没有完全取代PowerShell的旧版本,但Microsoft表示他们打算让Core系列最终取代旧Framework系列。当您阅读本文时,您的系统上可能会预装兼容版本的PowerShell;如果没有,请参阅https://github.com/powershell/powershell.

根据文档,PowerShell 7.0中开箱即用支持以下操作符

  1. 空合并:<代码>

这些工作与您期望的空合并一样:

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

由于引入了三元运算符,现在可以实现以下操作,但由于添加了空合并运算符,因此没有必要:

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

从7.0开始,如果启用了PSNull条件操作员可选功能,则以下内容也可用,如文档(1,2)中所述:

  1. 成员的空条件成员访问:?。
  2. 数组的空条件成员访问et al:?[]

这些有几个注意事项:

  1. 由于这些都是实验性的,它们可能会发生变化。当你读到这篇文章时,它们可能不再被认为是实验性的,警告列表可能已经改变了
  2. 如果后面跟着一个实验运算符,则变量必须括在${}中,因为变量名称中允许使用问号。目前尚不清楚,如果/当这些功能从实验状态毕业时,是否会出现这种情况(见第11379期)。例如,<代码>${x}?。Test()使用新运算符,但使用$x?。Test()在名为$x的变量上运行Test()
  3. 没有<代码>?(运算符,如果您来自TypeScript,您可能会想到。以下操作不起作用:x.Test?()

PowerShell 7之前的版本确实有一个实际的空合并运算符,或者至少有一个能够执行此类行为的运算符。该运算符是-ne

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

# Output:
alpha

它比空合并运算符更通用,因为它生成所有非空项的数组:

$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. 操作符从数组中筛选出与指定值匹配的所有项,在本例中为null。结果是一个非空值数组,其顺序与步骤1中创建的数组相同
  3. 用于选择筛选数组的第一个元素

简化:

  1. 按首选顺序创建可能值的数组

与C#'s null合并运算符不同,将对每个可能的表达式求值,因为第一步是创建数组。

居焱
2023-03-14

Powershell 7在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社区扩展,您可以使用标准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"

或者可能为,如果为空:

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脚本,它使用Start-Process cmdlet通过“以管理员身份运行”选项以编程方式启动进程: 由于不能为NULL或为空,我必须添加以避免ParameterArgumentValidationError错误。

  • 如果我的问题不能完全描述我在这里所问的问题,我深表歉意!我不知道如何筛选大括号/括号之间的字段内容或缺少。我的热门搜索结果返回了这篇文章,我认为这并不能解决我的问题。 我正在尝试从MSOnline/AzureAD中提取禁用/未设置多因素身份验证选项的所有用户。这一事实有点微不足道,但它设定了背景。。。。 我有下面的查询,它返回一个我知道没有配置StrongAuthenticationRequire

  • 问题内容: PHP中是否存在像C#一样的三元运算符? 在C#中更干净,更短,但是在PHP中,您必须执行以下操作: 问题答案: PHP 7添加了空合并运算符: 您还可以看一下编写PHP三元运算符?的简短方法:(仅PHP> = 5.3) 而且您与C#的比较是不公平的。“在PHP中,您必须做类似的事情”-在C#中,如果您尝试访问不存在的数组/字典项,那么还将出现运行时错误。

  • 为什么HashMap merge要对值进行null检查。HashMap支持null键和null值。那么有谁能告诉我为什么需要在合并时进行null检查吗?

  • 用于从CSV中删除空白列的Powershell脚本 我有一个电子表格,我正在将其导入MySQL数据库,由于电子表格中的空白列,导入失败。 是否有一个PowerShell脚本,我可以运行/创建,将检查任何给定的CSV文件并删除空白列? Col1,Col2,Col3,Col4,,,Val1,Val2,Val3,Val4

  • 在PowerShell中,是否有一个内置的类函数来检查字符串是空还是空? 到目前为止我还找不到它,如果有一个内置的方式,我不想为此写一个函数。