使用Select-String从文件中提取表数据

时间:2017-08-26 23:29:12

标签: powershell

这是我的示例文本文件,我正在尝试解析结果

2017-08-26 22:31:10,769 - Recv:  T:150.01 /150.00 B:59.77 /60.00 @:23 B@:127
2017-08-26 22:31:12,559 - Recv: echo:busy: processing
2017-08-26 22:31:12,768 - Recv:  T:150.04 /150.00 B:59.93 /60.00 @:22 B@:127
2017-08-26 22:31:13,660 - Recv: Bilinear Leveling Grid:
2017-08-26 22:31:13,665 - Recv:       0      1      2      3      4
2017-08-26 22:31:13,669 - Recv:  0 +0.203 +0.105 -0.020 -0.182 -0.275
2017-08-26 22:31:13,672 - Recv:  1 +0.192 +0.100 -0.028 -0.192 -0.310
2017-08-26 22:31:13,675 - Recv:  2 +0.138 +0.018 -0.090 -0.257 -0.340
2017-08-26 22:31:13,678 - Recv:  3 +0.117 +0.018 -0.087 -0.247 -0.362
2017-08-26 22:31:13,681 - Recv:  4 +0.105 -0.020 -0.122 -0.285 -0.385

我需要搜索并拆分内容,使其看起来像这样

      0      1      2      3      4
0 +0.203 +0.105 -0.020 -0.182 -0.275
1 +0.192 +0.100 -0.028 -0.192 -0.310
2 +0.138 +0.018 -0.090 -0.257 -0.340
3 +0.117 +0.018 -0.087 -0.247 -0.362
4 +0.105 -0.020 -0.122 -0.285 -0.385

这是我的尝试

Get-Content \\192.168.1.41\octoprint\logs\serial.log | Select-String "Bilinear Leveling Grid:" -Context 0,6 -SimpleMatch  | %{$_.Line.Split("Recv:  ")}

这是我的输出

2017-08-26
22
31
13,660
-






Bilin
ar
L


ling
Grid

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

如何使用-replace运算符

正则表达式在这里肯定有用,但Select-String不会成为我选择的工具。使用-replace运算符,我们可以在两个操作中获得您想要的内容。

# Read in the file as one string. 
$textData = Get-Content "\\192.168.1.41\octoprint\logs\serial.log" | Out-String

# Remove everything up to and including a line with Bilinear Leveling Grid: 
# and remove all the prefixes from remaining lines be deleted everything up until Recv: . 
$textData -replace "(?m)^.*?Bilinear Leveling Grid:\s+$" -replace "(?m)^.*?Recv: "

我们在正则表达式中使用多行修饰符,以便锚点^$匹配文本中行的开头和结尾,而不确定文本本身的开头和结尾。这样可以更轻松地删除文本的大小。

选择字符串

虽然我觉得我的方法更加强大,但我想展示一下如何通过Select-String

获得所需的结果
$result = $textData | Select-String "Bilinear Leveling Grid:" -Context 0,6 -SimpleMatch 
$result.Context.PostContext -replace "^.*?Recv: "

所以如果你知道它总是会有6行也能正常工作。同样在这个例子中,我们使用replace运算符从剩余的行中删除时间戳等。

为什么你的方法不起作用

当您使用上下文时,生成的MatchInfo对象将其存储在名为Context的属性中,就像您在上面的解决方案中看到的那样。 From the docs about Select-String and -Context

  

此参数不会更改Select-String生成的对象数。 Select-String为每个匹配生成一个MatchInfo(Microsoft.PowerShell.Commands.MatchInfo)对象。上下文存储为对象的Context属性中的字符串数组。

你没有提到它,这是你的结果是他们的方式的部分原因。所以我们在比赛结束后获得了上下文,这样就可以获得"表标题"之后的6行。

您的另一个问题是,您在匹配的一行上使用Split()并且拆分将在您传递的任何字符上划分该行而不是整个字符串。考虑"abcde".Split("bd"),它将构成一个3元素数组。

答案 1 :(得分:0)

试试这个:

$file="\\192.168.1.41\octoprint\logs\serial.log"
$delimiterrow="Bilinear Leveling Grid:"

Get-Content $file | Select-String $delimiterrow -Context 0,6 |%{ $_.Context.PostContext | %{ ($_ -split 'Recv:  ', 2)[1]}}

#short version
gc $file | sls $delimiterrow -Co 0,6 |%{ $_.Context.PostContext | %{ ($_ -split 'Recv:  ', 2)[1]}}