如何在PowerShell中将foreach更改为for?

如何在PowerShell中将foreach更改为for?,powershell,Powershell,我想打印文本文件中的单词exist并打印“match”和“not match”。我的第一个文本文件是:xxaavv6J,第二个文件是6J6SCa.yB 如果匹配,则返回如下所示: Match found: Match found: Match found: Match found: Match found: Match found: 6J Match found: Match found: Match found: foreach ($i in $Z) { if (if $

我想打印文本文件中的单词exist并打印“match”和“not match”。我的第一个文本文件是:
xxaavv6J
,第二个文件是
6J6SCa.yB

如果匹配,则返回如下所示:

Match found: Match found: Match found: Match found: Match found: Match found: 6J Match found: Match found: Match found:
foreach ($i in $Z) {
    if (if $Split -contains $i) {
        Write-Host "Match found: ${i}"
    }
}

操作
-split'(..)
不会产生您认为会产生的结果。如果查看以下命令的输出,您将看到得到许多空结果:

PS C:\> 'xxaavv6J' -split '(..)' | % { "-$_-" } -- -xx- -- -aa- -- -vv- -- -6J- -- 与

您还可以使用以下内容替换嵌套循环:

Match found: Match found: Match found: Match found: Match found: Match found: 6J Match found: Match found: Match found:
foreach ($i in $Z) {
    if (if $Split -contains $i) {
        Write-Host "Match found: ${i}"
    }
}

操作
-split'(..)
不会产生您认为会产生的结果。如果查看以下命令的输出,您将看到得到许多空结果:

PS C:\> 'xxaavv6J' -split '(..)' | % { "-$_-" } -- -xx- -- -aa- -- -vv- -- -6J- -- 与

您还可以使用以下内容替换嵌套循环:

Match found: Match found: Match found: Match found: Match found: Match found: 6J Match found: Match found: Match found:
foreach ($i in $Z) {
    if (if $Split -contains $i) {
        Write-Host "Match found: ${i}"
    }
}

使用regex“.Match()”的一种稍有不同的方法也可以做到这一点。
我为您添加了很多解释性评论:

$Test = Get-Content "C:\Users\2.txt" -Raw         # Read as single string. Contains "xxaavv6J"
$Data = (Get-Content "C:\Users\d.txt") -join ''   # Read as array and join the lines with an empty string. 
                                                  # This will remove Newlines. Contains "6J6SCa.yB"

# Split the data and make sure every substring has two characters
# In each substring, the regex special characters need to be Escaped.
# When this is done, we join the substrings together using the pipe symbol.
$Data = ($Data -split '(.{2})' |                                   # split on every two characters
        Where-Object { $_.Length -eq 2 } |                         # don't care about any left over character
        ForEach-Object { [Regex]::Escape($_) } ) -join '|'         # join with the '|' which is an OR in regular expression

# $Data is now a string to use with regular expression: "6J|6S|Ca|\.y"

# Using '.Match()' works Case-Sensitive. To have it compare Case-Insensitive, we do this:
$Data = '(?i)' + $Data

# See if we can find one or more matches
$regex = [regex]$Data
$match = $regex.Match($Test)
# If we have found at least one match:
if ($match.Groups.Count) {
    while ($match.Success) {
        # matched text: $match.Value
        # match start:  $match.Index
        # match length: $match.Length
        Write-Host ("Match found: {0}" -f $match.Value)
        $match = $match.NextMatch()
    }
}
else {
    Write-Host "Not Found"
}
结果:

找到匹配项:6J


使用regex“.Match()”的一种稍有不同的方法也可以做到这一点。
我为您添加了很多解释性评论:

$Test = Get-Content "C:\Users\2.txt" -Raw         # Read as single string. Contains "xxaavv6J"
$Data = (Get-Content "C:\Users\d.txt") -join ''   # Read as array and join the lines with an empty string. 
                                                  # This will remove Newlines. Contains "6J6SCa.yB"

# Split the data and make sure every substring has two characters
# In each substring, the regex special characters need to be Escaped.
# When this is done, we join the substrings together using the pipe symbol.
$Data = ($Data -split '(.{2})' |                                   # split on every two characters
        Where-Object { $_.Length -eq 2 } |                         # don't care about any left over character
        ForEach-Object { [Regex]::Escape($_) } ) -join '|'         # join with the '|' which is an OR in regular expression

# $Data is now a string to use with regular expression: "6J|6S|Ca|\.y"

# Using '.Match()' works Case-Sensitive. To have it compare Case-Insensitive, we do this:
$Data = '(?i)' + $Data

# See if we can find one or more matches
$regex = [regex]$Data
$match = $regex.Match($Test)
# If we have found at least one match:
if ($match.Groups.Count) {
    while ($match.Success) {
        # matched text: $match.Value
        # match start:  $match.Index
        # match length: $match.Length
        Write-Host ("Match found: {0}" -f $match.Value)
        $match = $match.NextMatch()
    }
}
else {
    Write-Host "Not Found"
}
结果:

找到匹配项:6J

进一步说明:如果您正在运行(以上)Windows PowerShell 4.0,则可以应用Kirk Munro详尽文章中描述的
.Where()
方法:

随着Windows PowerShell 4.0的发布,两个新的“神奇”方法 为提供新语法的集合类型引入 访问Windows PowerShell中的
ForEach
Where
功能。 这些方法被恰当地命名为ForEach和
,其中
。我打电话 这些方法之所以“神奇”,是因为它们的工作方式非常神奇 在PowerShell中。它们不会出现在
Get Member
输出中,即使您 应用
-Force
和请求
-MemberType All
。如果你卷起你的头发 袖子和挖掘与反射,你可以找到他们;但是, 需要广泛的搜索,因为它们是私有扩展方法 在私有类上实现。然而,即使他们不是 不用偷看就可以发现,当你 需要它们时,它们比年长的同类更快,而且 包括旧版本中不可用的功能 因此,当你离开时,他们会给你一种“神奇”的感觉 在PowerShell中使用它们。不幸的是,这些方法仍然存在 直到今天,他们还没有被记录在案,因为他们已经公开了将近一年 发布后,很多人没有意识到 这些方法。

Where方法

其中
是一种允许您过滤对象集合的方法。 这非常类似于
Where-Object
cmdlet,但是
Where
方法也类似于
选择对象
分组对象
, 包括
Where-Object
cmdlet支持的几个附加功能 本身不支持。这种方法提供了更快的速度 在一个简单、优雅的命令中,性能优于Where Object。喜欢 在
ForEach
方法中,此方法输出的任何对象都是 在类型为的泛型集合中返回
System.Collections.ObjectModel.Collection1[psobject]

此方法只有一个版本,可以描述为 如下:

Where(scriptblock expression[, WhereOperatorSelectionMode mode[, int numberToReturn]])
如方括号所示,
表达式
脚本块 必填项和
模式
枚举和
数字返回
整数 参数是可选的,因此可以使用1、2或3调用此方法 论据。如果要使用特定参数,必须提供 该参数左边的所有参数(即,如果您想 为
numberToReturn
提供值,您必须为
模式
以及
表达式

应用于您的案例(使用
.Where()
方法的最简单变体
Where(脚本块表达式)
):

例如,Ansgar的示例更改如下:

Where(scriptblock expression[, WhereOperatorSelectionMode mode[, int numberToReturn]])
PS > ('xxaavv6J' -split '(..)').Where{$_ -ne ''} | % { "-$_-" }
-xx-
-aa-
-vv-
-6J-
进一步说明:如果您正在运行(以上)Windows PowerShell 4.0,则可以应用Kirk Munro详尽文章中描述的
.Where()
方法:

随着Windows PowerShell 4.0的发布,两个新的“神奇”方法 为提供新语法的集合类型引入 访问Windows PowerShell中的
ForEach
Where
功能。 这些方法被恰当地命名为ForEach和
,其中
。我打电话 这些方法之所以“神奇”,是因为它们的工作方式非常神奇 在PowerShell中。它们不会出现在
Get Member
输出中,即使您 应用
-Force
和请求
-MemberType All
。如果你卷起你的头发 袖子和挖掘与反射,你可以找到他们;但是, 需要广泛的搜索,因为它们是私有扩展方法 在私有类上实现。然而,即使他们不是 不用偷看就可以发现,当你 需要它们时,它们比年长的同类更快,而且 包括旧版本中不可用的功能 因此,当你离开时,他们会给你一种“神奇”的感觉 在PowerShell中使用它们。不幸的是,这些方法仍然存在 直到今天,他们还没有被记录在案,因为他们已经公开了将近一年 发布后,很多人没有意识到 这些方法。

Where方法

其中
是一种允许您过滤对象集合的方法。 这非常类似于
Where-Object
cmdlet,但是
Where