如何在文本中选择一些匹配行并附加到powershell中的变量?

如何在文本中选择一些匹配行并附加到powershell中的变量?,powershell,Powershell,我发现这个讨论是基于命令行输出,而不是变量。我的文本在一个变量中 我正试图找到里面有旋律这个词的台词 $output = 'This is some data Only the lines with Melody should be included For instance Mozart is a Melody But Justin Biber Beauty and the Beast is not

我发现这个讨论是基于命令行输出,而不是变量。我的文本在一个变量中

我正试图找到里面有
旋律
这个词的台词

$output = 'This is some data
            Only the lines with Melody should be included
            For instance Mozart is a Melody
            But Justin Biber Beauty and the Beast is not
            Neither is anything Bieber ever did'

$skimmed = ''

$output | Where-Object { $_ -match '.*Melody.*' } | ForEach-Object {
                    $skimmed = $skimmed + $_ }
Write-Host $skimmed
它正在写入的输出如下

            This is some data
            Only the lines with Melody should be included
            For instance Mozart is a Melody
            But Justin Biber Beauty and the Beast is not
            Neither is anything Bieber ever did

如何仅拾取与我的模式匹配的行?

首先将
$output
中的文本块拆分为单独的行:

$output = 'This is some data
           Only the lines with Melody should be included
           For instance Mozart is a Melody
           But Justin Biber Beauty and the Beast is not
           Neither is anything Bieber ever did' -split '\r?\n'
\r?\n
将匹配所有换行符,无论它们是CRLF、LF还是CR

另外,我会把剩下的代码改成这样:

$skimmed = $output | Where-Object { $_ -match 'Melody' } # or use $_ -like '*Melody*'

Write-Host (-join $skimmed)

首先将
$output
中的文本块拆分为单独的行:

$output = 'This is some data
           Only the lines with Melody should be included
           For instance Mozart is a Melody
           But Justin Biber Beauty and the Beast is not
           Neither is anything Bieber ever did' -split '\r?\n'
\r?\n
将匹配所有换行符,无论它们是CRLF、LF还是CR

另外,我会把剩下的代码改成这样:

$skimmed = $output | Where-Object { $_ -match 'Melody' } # or use $_ -like '*Melody*'

Write-Host (-join $skimmed)
作为补充,它很好地解决了您的主要问题:

使用管道和cmdlet(如)很方便,但速度很慢。 如果不需要流式处理(一个接一个,在管道中),您可以通过直接在输入上使用PowerShell操作符来简化和加速过滤,因为比较操作符(如
-match
)能够作为其LH作用于阵列,在这种情况下,它们充当过滤器,返回匹配元素的子数组

因此,您的代码可以按如下方式重写,这既简洁又快速:

# Note the use of a here-string (@'<newline>...<newline>'@) 
$output = @'
This is some data
Only the lines with Melody should be included
For instance Mozart is a Melody
But Justin Biber Beauty and the Beast is not
Neither is anything Bieber ever did
'@ -split '\r?\n' 

# Since $output is an *array*, -match performs *filtering*.
$skimmed = $output -match 'Melody'
#注意此处字符串(@'…')的使用
$output=@'
这是一些数据
只应包括带有旋律的线条
比如莫扎特就是一首旋律
但贾斯汀·比伯的《美女与野兽》不是
比伯也没有做过任何事
“@-split”\r?\n”
#由于$output是一个*数组*,-match执行*过滤*。
$skimmed=$output-匹配“旋律”
注意:如果您真的想连接匹配的行以获得单行字符串,请使用
$skimmed=-join($output-match'Melody')

请注意,默认情况下,
-match
与输入字符串的子字符串匹配,因此只使用
'Melody'
作为正则表达式,而不是使用
.*Melody.*'

作为补充就足够了,这很好地解决了您的主要问题:

使用管道和cmdlet(如)很方便,但速度很慢。 如果不需要流式处理(一个接一个,在管道中),您可以通过直接在输入上使用PowerShell操作符来简化和加速过滤,因为比较操作符(如
-match
)能够作为其LH作用于阵列,在这种情况下,它们充当过滤器,返回匹配元素的子数组

因此,您的代码可以按如下方式重写,这既简洁又快速:

# Note the use of a here-string (@'<newline>...<newline>'@) 
$output = @'
This is some data
Only the lines with Melody should be included
For instance Mozart is a Melody
But Justin Biber Beauty and the Beast is not
Neither is anything Bieber ever did
'@ -split '\r?\n' 

# Since $output is an *array*, -match performs *filtering*.
$skimmed = $output -match 'Melody'
#注意此处字符串(@'…')的使用
$output=@'
这是一些数据
只应包括带有旋律的线条
比如莫扎特就是一首旋律
但贾斯汀·比伯的《美女与野兽》不是
比伯也没有做过任何事
“@-split”\r?\n”
#由于$output是一个*数组*,-match执行*过滤*。
$skimmed=$output-匹配“旋律”
注意:如果您真的想连接匹配的行以获得单行字符串,请使用
$skimmed=-join($output-match'Melody')

请注意,
-match
默认情况下匹配输入字符串的子字符串,因此只使用
'Melody'
作为正则表达式,而不是使用
'.*Melody.*'