使用PowerShell从多个文件中提取行

时间:2017-10-25 09:30:24

标签: powershell

我遇到了需要分析日志/文本文件数据的情况。有数百个文件,有时数万行数据。我只使用PowerShell,因为它可以在我的计算机上使用,而且我可以说是足够的。仅仅使用Google并在此处查找主题,我就设法创建了一个脚本,该脚本将解析一个特定标签的多个文件并提取整个数据行。

问题是我想从文件中提取多行不同的数据,主要是我要查找的实际数据和日期。如果我能将提取的数据提取到Excel文件中也会很好。现在它被提取到一个文本文件,我只是剪切并粘贴到Excel,然后将格式从文本更改为列,并用空格分隔。

以下是我正在查看的文字示例。

3I  "MAC" "DATE" := 2016, 8, 1
3I  "MAC" "TIME" := 3, 42, 56
15F  "MAC" "ORGB" := -1.656704e-04, -1.878277e-04, -1.873876e-04, -1.659016e-04, -1.429739e-04, -1.786126e-04, -1.590039e-04, -2.246118e-04, -1.951066e-04, -2.158172e-04, -1.526934e-04, -1.560605e-04, -1.856570e-04, -2.192611e-04, -1.747964e-04
15F  "MAC" "ORGP" := -1.657223e-04, -1.878391e-04, -1.874067e-04, -1.659254e-04, -1.429638e-04, -1.786519e-04, -1.590114e-04, -2.245719e-04, -1.950584e-04, -2.158372e-04, -1.526876e-04, -1.561122e-04, -1.855181e-04, -2.192713e-04, -1.748256e-04
15F  "MAC" "OFF3" := -7.424393e-08, -1.599836e-07, 1.178269e-07, 3.231106e-07, -4.113245e-07, -4.851174e-07, 4.043978e-07, 3.279856e-07, 6.228656e-07, 1.257285e-07, 1.290027e-07, -1.727165e-07, 7.661874e-07, 1.182343e-07, 1.484092e-06
15F  "MAC" "POST" := -1.897504e-06, 1.557098e-05, -1.367209e-05, -8.604270e-06, -1.810627e-06, 1.041628e-05, -6.231011e-06, 1.683000e-05, -1.059830e-05, 8.980048e-06, -1.064588e-06, -7.914769e-06, -1.680518e-05, 2.467031e-05, -7.863747e-06
15F  "MAC" "OFF4" := -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00
15F  "MAC" "PRID" := -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00, -1.000000e+00
15I  "MAC" "SOPC" := -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1

这是我正在使用的脚本,它需要大约30分钟的时间,并最终耗尽我的所有内存,因为它可能不是我想要做的最佳方式。

$log = Get-Content "C:\Users\derekru\Documents\WS FTP Pro\MACBAC\MACSENS_*.txt;1"
foreach ($line in $log) { 
    if ($line -like "*OFF3*") {
        $line | Out-File -FilePath "D:\Work\MACSENS\Graph\STP09\160801-171022.txt" -Append
    }
}

最终,我希望能够提取"日期","时间"," ORGB"," ORGP",以及" OFF3"从多个文件到excel,所以它的格式化

Date, Time, ORGB, the 15 data points, ORGP, the 15 points of data, OFF3, the 15 points of data...

在一个Excel行上。

2 个答案:

答案 0 :(得分:1)

首先:单独处理文件,特别是如果您有大文件。在处理之前将所有文件的内容读入一个变量必然会使系统陷入困境。

Get-ChildItem 'C:\path\to\file_*.txt' | ForEach-Object {
    ...
} | Set-Content 'D:\path\to\output.txt'

对于每个文件,读取前两行并提取日期和时间:

$d1 = Get-Content $_.FullName -TotalCount 2 |
      ForEach-Object { ($_ -split '\s*:=\s*')[1] }
$d2 = $d1 -join ', '

$pattern = 'yyyy, M, d, h, m, s'
$culture = [Globalization.CultureInfo]::InvariantCulture
$timestamp = [DateTime]::ParseExact($d2, $pattern, $culture)

从文件的其余部分中提取数据:

$data = Get-Content $_.FullName |
        Select-Object -Skip 2 |
        Where-Object { $_ -match '"(.*?)"\s*:=\s*(.*)' } |
        ForEach-Object { '{0},{1}' -f $matches[1,2] }

并输出如下:

$timestamp.ToString('yyyy-MM-dd,HH:mm:ss') + ',' + ($data -join ',')

然后将文本文件导入Excel。

答案 1 :(得分:0)

您可以使用Select-String更快地(更可读地使用imo)执行此操作。

Select-String -Path $File -Pattern 'OFF3' -SimpleMatch | Out-File -FilePath $Path -Append

如果运行时非常重要,那么最好使用底层.net命令,编译语言,为此类设计的第三方工具或并行/线程方法。

如果你想将多行组合成一个,并且每个块总共有9行的块,你可以使用

Select-String '"DATE"' -Context 0,9

然后遍历生成的对象并使用Context对象来匹配您的信息,尽管这可能是缓慢而复杂的。