在 Powershell 中过滤具有多个条件的 Foreach-Object 结果不起作用
filter Foreach-Object results with multiple conditions in Powershell not working
我正在尝试使用 Powershell 7 过滤 git 中已更改文件的列表。我只想要以 'packages' 或 'database' 开头的文件路径。当我 运行 代码时,结果没有被过滤,所有的东西都被返回了。我怎样才能让过滤工作?我是 Powershell 脚本的新手。
这是我的代码:
$editedFiles = git diff HEAD [git commit id] --name-only
$editedFiles | ForEach-Object {
$sepIndex = $_.IndexOf('/')
if($sepIndex -gt 0 -and ($_ -contains 'packages' -or 'database')) {
Write-Output $_
}
}
这里有两点需要注意:
-contains
是一个 集合包含运算符 - 对于字符串,您需要 -like
通配符比较运算符:
$_ -like "*packages*"
或 -match
正则表达式运算符:
$_ -match 'package'
这里要注意的另一件事是 -or
运算符 - 它只需要 布尔值 操作数 ($true
/$false
) ,如果你传递任何其他东西,它会 convert 操作数到 [bool]
如有必要。
也就是说下面这种语句:
$(<# any expression, really #>) -or 'non-empty string'
ALWAYS returns $true
- 因为非空字符串在转换为 [bool]
.
时计算结果为 $true
相反,您需要更改两个单独的比较:
$_ -like '*packages*' -or $_ -like '*database*'
或者,您可以使用 -match
运算符 一次,方法是使用交替 (|
):
$_ -match 'package|database'
最后得到类似的东西:
$editedFiles | ForEach-Object {
$sepIndex = $_.IndexOf('/')
if($sepIndex -gt 0 -and $_ -match 'package|database') {
Write-Output $_
}
}
如果过滤是您打算在 ForEach-Object
块中执行的所有操作,您不妨使用 Where-Object
- 它的设计 正是 为此 :)
$editedFiles | Where-Object {
$_.IndexOf('/') -gt 0 -and $_ -match 'package|database'
}
我正在尝试使用 Powershell 7 过滤 git 中已更改文件的列表。我只想要以 'packages' 或 'database' 开头的文件路径。当我 运行 代码时,结果没有被过滤,所有的东西都被返回了。我怎样才能让过滤工作?我是 Powershell 脚本的新手。
这是我的代码:
$editedFiles = git diff HEAD [git commit id] --name-only
$editedFiles | ForEach-Object {
$sepIndex = $_.IndexOf('/')
if($sepIndex -gt 0 -and ($_ -contains 'packages' -or 'database')) {
Write-Output $_
}
}
这里有两点需要注意:
-contains
是一个 集合包含运算符 - 对于字符串,您需要 -like
通配符比较运算符:
$_ -like "*packages*"
或 -match
正则表达式运算符:
$_ -match 'package'
这里要注意的另一件事是 -or
运算符 - 它只需要 布尔值 操作数 ($true
/$false
) ,如果你传递任何其他东西,它会 convert 操作数到 [bool]
如有必要。
也就是说下面这种语句:
$(<# any expression, really #>) -or 'non-empty string'
ALWAYS returns $true
- 因为非空字符串在转换为 [bool]
.
$true
相反,您需要更改两个单独的比较:
$_ -like '*packages*' -or $_ -like '*database*'
或者,您可以使用 -match
运算符 一次,方法是使用交替 (|
):
$_ -match 'package|database'
最后得到类似的东西:
$editedFiles | ForEach-Object {
$sepIndex = $_.IndexOf('/')
if($sepIndex -gt 0 -and $_ -match 'package|database') {
Write-Output $_
}
}
如果过滤是您打算在 ForEach-Object
块中执行的所有操作,您不妨使用 Where-Object
- 它的设计 正是 为此 :)
$editedFiles | Where-Object {
$_.IndexOf('/') -gt 0 -and $_ -match 'package|database'
}