如果在PowerShell中不包含任何数组值,则写出字符串

时间:2022-04-26 07:41:41

I have a simple program here that will write out a line within an array of lines if it does not contain any of the names within another array.

我这里有一个简单的程序,如果它不包含另一个数组中的任何名称,它将在行数组中写出一行。

[array]$names = "Adam", "Bill", "Colin", "Dave"

[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

foreach ($line in $lines)
{
   if ($line -notmatch $names)
   {
       write $line
   }
}

When I run this, it just writes out every line from the array of lines, even though 'Adam' is included in the array of names. It should just write out 'My name is Jim' and 'My name is Sam'.

当我运行它时,它只是写出行数组中的每一行,即使'Adam'包含在名称数组中。它应该写出'我的名字是吉姆'和'我的名字是山姆'。

Sorry if this question is pretty basic but I couldn't find any answers for it.

很抱歉,如果这个问题非常基本,但我找不到任何答案。

3 个解决方案

#1


1  

There is probably a better solution than this, but one way to solve it is to have a second loop that iterates through each name and checks for them in the line:

可能有一个比这更好的解决方案,但解决它的一种方法是使用第二个循环遍历每个名​​称并在行中检查它们:

[array]$names = "Adam", "Bill", "Colin", "Dave"
[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

foreach ($line in $lines)
{
    $names | ForEach-Object -Begin {$found = $false} {
        If ($line -match $_){ $found = $true; break } 
    } 

    if (-not $found)
    {
        write $line
    }
}

Explanation:

  • Sends $names via the pipeline in to ForEach-Object. This starts by initializing a $found variable within it's -Begin block.
  • 通过管道将$ name发送到ForEach-Object。首先在它的-Begin块中初始化$ found变量。

  • ForEach-Object checks the line to match against each name (the name is now an item in the pipeline represented by $_). If it is found it sets $found to true and uses break to end the loop.
  • ForEach-Object检查该行是否与每个名称匹配(该名称现在是由$ _表示的管道中的项目)。如果找到它将$ found设置为true并使用break来结束循环。

  • If $found is not true, it writes the line.
  • 如果$ found不成立,则写入该行。

#2


2  

If you are using a regex comparison with -notmatch why not turn your list of names into a better regex? How about something like this:

如果你正在使用与-notmatch的正则表达式比较,为什么不把你的名字列表变成一个更好的正则表达式?这样的事情怎么样:

$names = "Adam", "Bill", "Colin", "Dave"
$lines = "My name is Jim", "My name is Sam", "My name is Adam"

$regex = $names -join '|'

$lines | ? {$_ -notmatch $regex} | % {Write-Host $_}

#3


0  

Thanks for the answers guys. I have reworked my code to make it a little simpler:

谢谢你的回答。我重新编写了我的代码,使其更简单:

[array]$names = "Adam", "Bill", "Colin", "Dave"

[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

    foreach ($line in $lines)
    {
        $regex = $names -join '|'

        if ($line -notmatch $regex)
        {
            write $line
        }
    }

#1


1  

There is probably a better solution than this, but one way to solve it is to have a second loop that iterates through each name and checks for them in the line:

可能有一个比这更好的解决方案,但解决它的一种方法是使用第二个循环遍历每个名​​称并在行中检查它们:

[array]$names = "Adam", "Bill", "Colin", "Dave"
[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

foreach ($line in $lines)
{
    $names | ForEach-Object -Begin {$found = $false} {
        If ($line -match $_){ $found = $true; break } 
    } 

    if (-not $found)
    {
        write $line
    }
}

Explanation:

  • Sends $names via the pipeline in to ForEach-Object. This starts by initializing a $found variable within it's -Begin block.
  • 通过管道将$ name发送到ForEach-Object。首先在它的-Begin块中初始化$ found变量。

  • ForEach-Object checks the line to match against each name (the name is now an item in the pipeline represented by $_). If it is found it sets $found to true and uses break to end the loop.
  • ForEach-Object检查该行是否与每个名称匹配(该名称现在是由$ _表示的管道中的项目)。如果找到它将$ found设置为true并使用break来结束循环。

  • If $found is not true, it writes the line.
  • 如果$ found不成立,则写入该行。

#2


2  

If you are using a regex comparison with -notmatch why not turn your list of names into a better regex? How about something like this:

如果你正在使用与-notmatch的正则表达式比较,为什么不把你的名字列表变成一个更好的正则表达式?这样的事情怎么样:

$names = "Adam", "Bill", "Colin", "Dave"
$lines = "My name is Jim", "My name is Sam", "My name is Adam"

$regex = $names -join '|'

$lines | ? {$_ -notmatch $regex} | % {Write-Host $_}

#3


0  

Thanks for the answers guys. I have reworked my code to make it a little simpler:

谢谢你的回答。我重新编写了我的代码,使其更简单:

[array]$names = "Adam", "Bill", "Colin", "Dave"

[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

    foreach ($line in $lines)
    {
        $regex = $names -join '|'

        if ($line -notmatch $regex)
        {
            write $line
        }
    }