我目前有一个类似于此的日志文件:
<AutoRun>
<Info>Log file enabled: C:\Sync.xml</Info>
<Info>Exit attribute has been enabled.</Info>
<Info>Launching command: Run</Info>
<Run>
<Info></Info>
<Info></Info>
</Run>
<Infolog>
get Number of failures: 0
Number of Warnings: 0
Have resolvable Warnings: False
Number of Operations: 5
Number of Conflicts: 0
Get C:\ with ChangeType: None and Status: Replacing.
Get C:\ with ChangeType: None and Status: Replacing.
Get C:\ with ChangeType: None and Status: Replacing.
</Infolog>
</AutoRun>
我试图解析文本并执行以下操作:
干净地获取文字行
示例:失败次数:0,警告次数:0
获取以下值后的值:
我通过这样做得到了文本:
[xml]$Log = get-content "C:\Synchronize.xml"
$results = $Log.AutoRun.Infolog
并且认为我可以通过这样做来检索这条线:
Select-String -InputObject $a -Pattern 'Number of failures:'
但这会返回infolog节点中的所有内容,而不仅仅是我之后的行。我正在努力理解如何完成这两项任务。
这是我在阅读前两条建议后得出的结论。:
string[]]$Log = get-content "C:\Synchronize.xml"
$results = $Log | Select-String -Pattern 'Number of failures:\s+(\d+)' | %{$_.Matches.Groups.Value[1]}
答案 0 :(得分:1)
Select-String为InputObject参数获取String[]
。但是,XML元素是一个带有嵌入换行符的单个字符串。您传入的是单个字符串并在其中搜索而不是单独的行。
如果要将此字符串与Select-String一起使用,则需要先将其拆分为行。您可以使用String.Split方法执行此操作。您还可以将String.Trim应用于结果以修剪空白以获得更清晰的文本行。
$results = $Log.AutoRun.Infolog.Split("`n") | % { $_.Trim() }
$results | Select-String -Pattern 'Number of failures:'
请注意,当传入InputObject时,PowerShell的行为与用作参数的行为不同,因此您需要管道string[]
以搜索每个字符串。
来自https://technet.microsoft.com/en-us/library/hh849903.aspx:
使用InputObject参数与管道字符串不同 选择字符串。差异如下:
- 当您将多个字符串(&#34;集合&#34;)传递给Select-String时,Select-String会搜索每个字符串中的指定文本 string并返回包含搜索文本的每个字符串。
- 使用InputObject参数提交字符串集合时,Select-String将集合视为单个组合 string,如果找到搜索文本,则将字符串作为一个单元返回 在任何字符串中。
答案 1 :(得分:0)
还有更多内容,但问题的根源是带有InfoLog文本的文本被读作一个单独的字符串。如果你看这个,你会得到更符合你期望的结果。我不认为这是最好的解决方案,但它突出了问题
$Log.AutoRun.Infolog -split "[`r`n]" | Select-String -Pattern 'Number of failures'
Select-String
将返回包含匹配项的字符串。因此,在您的示例中,它将返回您请求的匹配项。 David's answer更详细地说明了这一点的原因,这里再说一遍是多余的。
认为您至少需要PowerShell 3.0,但是您可以隔离数字并从Select-String
返回的匹配对象中提取它。
$Log.AutoRun.Infolog | Select-String -Pattern 'Number of failures:\s+(\d+)' | %{$_.Matches.Groups.Value[1]}
Select-String
默认返回Microsoft.PowerShell.Commands.MatchInfo
而不是基本字符串。它们具有关于定义的匹配的各种属性。如果未指定任何属性,则默认返回整个匹配项。但是,我想深入研究属性,我想提取正则表达式(\d+)
中定义的捕获组。如果从右到左删除属性,您可以更好地了解其中的内容。
$_.Matches.Groups.Value
$_.Matches.Groups
$_.Matches
%
是ForEach-Object
的别名,我忘记删除。可以返回多个匹配项。我们将结果视为一个数组并检查每个数组。
假设该行总是有数字,它将只返回“:”之后的数字。如果它有返回单词的更改,您可以使用\S+
代替\d+