提取线,并从文件中的行基于现场的部分使用正则表达式

问题描述:

-CASServer V2.00 connection from 127.0.0.1 [] Diag mode only 
Clients: Static 0/50 Dynamic 17/50 
Sampler: 1 0x1074bd8 hSock(0x2d0) 
Archiver: 0 0 
OK  
0x1078b08:0x2fc 192.168.2.182 WorkStation84021 Dynamic 07:55:25 07/20/17  
0x1076d78:0x370 192.168.6.158 WorkStation84144 Dynamic 08:19:29 07/20/17  
0x1076f28:0x38c 192.168.3.75 WorkStation21590 Dynamic 08:27:56 07/20/17  
0x1089a98:0x394 192.168.12.147 WorkStation93778 Dynamic 08:29:50 07/20/17  
0x1089d68:0x378 192.168.2.200 WorkStation53283 Dynamic 08:34:03 07/20/17  
0x108a038:0x2d8 192.168.4.145 WorkStation38642 Dynamic 08:35:19 07/20/17  
0x108a308:0x35c 192.168.5.103 WorkStation35979 Dynamic 08:44:24 07/20/17  
0x108be80:0x37c 192.168.6.155 WorkStation53023 Dynamic 08:49:48 07/20/17  
0x107b7f8:0x360 192.168.5.104 WorkStation53269 Dynamic 08:50:45 07/20/17  
0x107bac8:0x384 192.168.2.244 WorkStation53297 Dynamic 08:51:53 07/20/17  
0x107bd98:0x36c 192.168.4.157 WorkStation53239 Dynamic 08:54:01 07/20/17  
0x107c230:0x3a4 192.168.5.7 WorkStation53229 Dynamic 08:59:29 07/20/17  
0x107c7e0:0x3ac 192.168.12.146 WorkStation93784 Dynamic 08:59:31 07/20/17  
0x107ce60:0x3b0 192.168.4.173 WorkStation53179 Dynamic 09:01:12 07/20/17  
0x107c710:0x3b4 192.168.2.175 WorkStation53047 Dynamic 09:02:06 07/20/17  
0x107cf30:0x368 192.168.5.85 SERVER53116 Dynamic 09:05:14 07/20/17  
0x107c3d0:0x3a8 192.168.5.126 WorkStation53279 Dynamic 09:06:36 07/20/17  
OK  
Unknown DIAG command  
OK 

我需要解析这个文本文件帮助。我想获得第二行“Dynamic#/ 50”,并想提取它。提取线,并从文件中的行基于现场的部分使用正则表达式

我也想知道是否有一个工作站名称以SERVER开头 如果找到了一个,那么我想提取IP,工作站名称和时间/日期。

我不确定解决这个问题的最佳方法是什么。 我知道我的文件不会很大(最多的行数大约是70行)。出于某种原因,我的Telnet输出是增加每个语句

+1

你能告诉我们输出是如何产生的吗?这是否是我们可以使用的另一个PowerShell脚本的结果,或者这是您要解析的文件或原始命令输出的原始内容? –

+1

在Ty的要求之上....你有没有看过如何解析这个文件?最好是看看你的方法,这样我们就可以告诉你哪里出了问题,并帮助你改进。 – Matt

+0

到目前为止您尝试过哪些方法,结果如何? –

之间的空白行最方便的(虽然速度慢)的方式来提取线是使用Select-String

> (Get-Content file | Select-String -List '\bDynamic \d+/50\b').Line 
Clients: Static 0/50 Dynamic 17/50 

虽然Select-String接受多个正则表达式,您甚至可以仅从的.Matches属性中提取匹配部分/捕获组Select-String属性输出的10个实例,您的复杂提取需求使得Select-String不切实际。

因此,定制逻辑是必需的:

注意:下面的溶液读取输入文件到存储器整体,这是可行与输入文件像您; 较大文件(或加工命令输出),使用具有ForEach-Object一个基于管线的解决方案,这将是比较慢,但是存储器效率 - 见底部:

# Read the entire file into an array of strings (line by line). 
$lines = Get-Content file 

# Extract the "DynamiC#/50" line 
$lines -match '\bDynamic \d+/50\b' # an array-valued LHS makes -match act as a filter 

# Extract the server information. 
foreach ($line in $lines) { 
    $fields = -split $line # split the line Awk-style into whitespace-separated fiels 
    if ($fields[2] -match '^Server') { # check if 2nd fields starts with 'Server' 
    $fields[1, 2, 4, 5] -join ' ' # join the fields of interest with a space and output 
    } 
} 

上面得到:

Clients: Static 0/50 Dynamic 17/50 
192.168.5.85 SERVER53116 09:05:14 07/20/17 

等效基于管线的溶液

再次,这将是更高的内存效率,但更慢
抛开了性能问题,基于流水线的解决方案通常更加简洁和概念优雅

Get-Content file | ForEach-Object { 
    if ($_ -match '\bDynamic \d+/50') { 
    $_ # output line as is 
    } elseif (($fields = -split $_) -and $fields[2] -match '^Server') { 
    $fields[1, 2, 4, 5] -join ' ' # output fields of interest, joined with spaces 
    } 
} 

您没有向社区提供其他人可以学习的脚本,所以我不愿意为您发布完整的答案。我会给你一个*别的评估,如果你发布你的脚本,仍然有问题,那么我会进一步帮助你。

您的文件有3个分区内容格式。每个都需要不同的解析方法。我们可以将它们称为顶部,中部和底部,我们可以通过“确定”文本将它们分开。我们也可以忽略底部内容区域,因为它不包含任何有用的数据。

开始通过获取文件的内容: $rawContent = get-content "c:\temp\yourfile.txt"

现在通过“确定”串打破内容: $contentAreas = ($rawContent -split "Ok")

现在每个内容区域可以另行制定。 $contentAreas[0]将输出顶部集 $contentAreas[1]将输出中间数据集

我建议你与中部地区第一个工作,因为它是稍微容易。在这里,您可以使用where子句来查找匹配“SERVER”的行。然后你可以解析你想要的值。

接下来,您可以使用顶部区域。在这里我建议你使用.Split()来通过空格(空格,制表符和新行)来分割内容。然后,您可以使用.IndexOf按名称查找字段并从那里开始工作。

同样,如果您发布了一些显示工作量并给予我合作的东西,我们将很乐意为您提供进一步的帮助。