[英]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.