【问题标题】:Using PowerShell to extract lines from multiple files使用 PowerShell 从多个文件中提取行
【发布时间】:2017-10-25 09:30:23
【问题描述】:

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

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

这是我正在查看的文本示例。

3I "MAC" "日期" := 2016, 8, 1 3I "MAC" "时间" := 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.683000 e-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 分钟,最终消耗了我所有的 RAM,因为它可能不是做我想做的事情的最佳方式。

$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, ORRGB, 15个数据点, ORGP, 15个数据点, OFF3, 15个数据点...

在 Excel 的一个行上。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    首先:单独处理您的文件,尤其是在您有大文件的情况下。在处理之前将所有文件的内容读取到一个变量中势必会导致系统瘫痪。

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

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

    $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。

    【讨论】:

    • 感谢您的意见。我会尝试吸收这一点,看看我能做些什么,然后回复你。即使有别的,单独处理文件也会有很大帮助。就像我说的那样,我对编程一无所知,所以可能需要一点时间。我要注意的一件事是,这个文本示例在同一个文件中重复了数千次,只是在特定标签之后有不同的数据。所以查找日期并不像处理前两行那么简单。
    【解决方案2】:

    您可以使用Select-String 更快地完成此操作(并且更易读)。

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

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

    如果你想将多行合并为一个,并且总是有一个块,每个块正好有 9 行,你可以使用

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

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

    【讨论】:

    • Ansgar 所做的编辑删除了“绒毛”,但我认为声明我对编码一无所知很重要。所以没有冒犯,但我不知道你在说什么。我将不得不尝试看看这些事情的含义并回复您。
    • @Derek 老实说,如果您是编码的绝对新手,您可能应该考虑将其分解为组件步骤,然后单独处理每个步骤,或者从头开始学习 powershell。
    • 这确实是个好主意。但它只是掉在我的腿上,所以我只是想充分利用它。我们有一个 IT 部门和编码人员,但试图让他们提供帮助就像拔牙一样。所以我放弃了询问,决定试一试。
    • @Derek “我对编码一无所知”不被接受为 SO 的借口。您至少应具备所选语言的基本知识(这意味着您已经完成了初学者级别的教程)。
    • @AnsgarWiechers 这可能是您的期望。我没有看到这种期望实际上在 SO 的任何地方说明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 2018-12-10
    相关资源
    最近更新 更多