简体   繁体   English

如何在 Powershell 中使用 select-string 进行多个管道

[英]How to do multiple piping with select-string in Powershell

I googled but did not found what I'm looking for.我用谷歌搜索但没有找到我要找的东西。

I have a big file containing list of countries and people.我有一个包含国家和人员列表的大文件。 I am aware how to do multiple piping in Linux, but the same way did not work for me in Powershell.我知道如何在 Linux 中进行多个管道,但同样的方法在 Powershell 中对我不起作用。

This is what I looked for and got nothing:这就是我寻找的,一无所获:

Select-String .\file -pattern 'country:[ ]{8}IR' -context 5 | Select-String -pattern 'names'

But if I separate this command into to, like below, works (in which I want to avoid creating a file to search):但是,如果我将此命令分成如下所示的工作(我想避免创建要搜索的文件):

Select-String .\file -pattern 'country:[ ]{8}IR' -context 5 > country
Select-String .\file -patern 'names'

* Update 1 *更新 1

Sample data after first grep is:第一个 grep 之后的示例数据是:

  file:1407215:names:        Hadi
  file:1407216:company:        sample
  file:1407217:city:          Tehran
  file:1407218:district:          8
  file:1407219:country:        IR
  file:1407220:admin:        Mahmoud
  file:1407221:tech:         Hamed
  file:1407222:seller:        sell@company
  file:1407223:status:         Active
  file:1407224:id:         12456

Select-String doesn't return a [string] (or array of strings) but an object of type [MatchInfo] . Select-String不返回[string] (或字符串数​​组),而是返回[MatchInfo]类型的对象。 The output of a MatchInfo may look like a multi line text but is split in the properties .Context.PreContext , .Line and .Context.PostContext . MatchInfo 的输出可能看起来像多行文本,但在属性 .Context.PreContext 、 .Context.PreContext.Line中被拆分.Context.PostContext So you can't use this object directly to pipe it into Select-String again.因此,您不能直接使用此对象再次将其通过管道传输到Select-String中。

However you can cast the output to [String] , -split it at the new lines and use Select-String over this array:但是,您可以将输出转换为[String] ,在新行处-split它并在此数组上使用Select-String

$MatchInfo = Select-String $file -pattern 'country:[ ]{8}IR' -context 5
[string]$MatchInfo -split [environment]::NewLine | Select-String -pattern 'names'

From a PowerShell perspective you will be dealing with objects most of the time, it might be a good idea to get the hang of dealing with them, hence this answer can show you an alternative to parsing your file into an array of objects which can be easily manipulated, filtered, sorted and exported into structured data (such as Csv) .从 PowerShell 的角度来看,您大部分时间都在处理对象,掌握处理它们的窍门可能是一个好主意,因此这个答案可以向您展示一种将文件解析为对象数组的替代方法,这些对象数组可以是易于操作、过滤、排序和导出为结构化数据(例如 Csv)

Supposing the test.txt looks similar to this:假设test.txt看起来像这样:

names:        Hadi
company:        sample
city:          Tehran
district:          8
country:        IR
admin:        Mahmoud
tech:         Hamed
seller:        sell@company
status:         Active
id:         12456

names:        John
company:        sample
city:          Tehran
district:          8
country:        IR
admin:        Doe
tech:         Hamed
seller:        sell@company
status:         Disabled
id:         12456

For this particular case we can use a switch with the -File parameter to read the file and the -Regex switch for the conditional clauses to start capturing and outputting the capture data as objects :对于这种特殊情况,我们可以使用带有-Regex参数的switch来读取文件,并使用-File开关让条件子句开始捕获并将捕获数据作为对象输出

$parsed = switch -Regex -File .\test.txt {
    # line starts with "names", signal to start capturing
    '^names' {
        $startcapture = $true
        $out = [ordered]@{}
    }
    # boolean is set to `$true`, capture this line and add it to the ordered dictionary
    { $startcapture } {
        $key, $value = $_.Split(':').Trim()
        $out[$key] = $value
    }
    # line starts with "id", signal to output the object, and restart the capture boolean
    '^id' {
        $startcapture = $false
        [pscustomobject] $out
    }
}

After parsing the test.txt file with above switch, $parsed would look like this:使用上述开关解析test.txt文件后, $parsed将如下所示:

names company city   district country admin   tech  seller       status   id
----- ------- ----   -------- ------- -----   ----  ------       ------   --
Hadi  sample  Tehran 8        IR      Mahmoud Hamed sell@company Active   12456
John  sample  Tehran 8        IR      Doe     Hamed sell@company Disabled 12456

Now $parsed can be exported to structured data at ease with Export-Csv and imported back as objects with Import-Csv :现在$parsed可以使用Export-Csv轻松导出到结构化数据,并使用Import-Csv作为对象导入回来:

$parsed | Export-Csv parseddata.csv -NoTypeInformation
$csv = Import-Csv parseddata.csv

It can also be filtered very easily a filtering cmdlet such as Where-Object :它也可以很容易地被过滤 cmdlet 过滤,例如Where-Object

# this array of objects where the `country` property value is equal to "IR"
# AND this array of objects where the `names` property value is equal to "Hadi"
$parsed | Where-Object { $_.country -eq 'IR' -and $_.names -eq 'Hadi' }

Which results in:结果是:

names    : Hadi
company  : sample
city     : Tehran
district : 8
country  : IR
admin    : Mahmoud
tech     : Hamed
seller   : sell@company
status   : Active
id       : 12456

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM