gpt4 book ai didi

powershell - 如何使用Powershell转换文件内容

转载 作者:行者123 更新时间:2023-12-03 00:24:52 25 4
gpt4 key购买 nike

我有一个奇怪的格式的日志文件,我想转换成表格。格式是每行包含多个键值对(每行相同)。我想转换这些行,以便每个属性成为包含该行值的表中的一列。

请注意,原始日志文件每行包含39个属性,日志文件约为80MB。

示例行:

date=2019-12-02 srcip=8.8.8.8 destip=8.8.4.4 srcintf="port2"
date=2019-12-01 srcip=8.8.8.8 destip=8.8.4.4 srcintf="xyz abc"
date=2019-12-03 srcip=8.8.8.8 destip=8.8.4.4 srcintf="port2"
date=2019-12-05 srcip=8.8.8.8 destip=8.8.4.4 srcintf="port2"
date=2019-12-07 srcip=8.8.8.8 destip=8.8.4.4 srcintf="port2"

我努力了:
Get-Content .\testfile.log | select -First 10 | ConvertFrom-String | select p1, p2, p3 | ft | Format-Wide

但这不会将属性名称分解为列名称。因此,在此示例中,我希望P1是日期,p2 srcip和p3 destip,并且希望删除每个值的第一部分。

Po

任何人都有任何技巧或创意,如何将其转换为表格?

最佳答案

ConvertFrom-String 提供基于分隔符的解析以及基于包含示例值的模板的基于启发式的解析。基于分隔符的解析会应用您无法控制的自动类型转换,并且模板语言的文档很少,准确的行为很难预测-,最好完全避免使用此cmdlet 。另请注意,它在PowerShell [Core] v6 +中不可用。

相反,我建议一种基于 switch statement [1]和 -split operator的方法来创建代表日志行的自定义对象([pscustomobject])的集合:

# Use $objects = switch ... to capture the generated objects in a variable.
switch -File .\testfile.log { # Loop over all file lines
default {
$oht = [ordered] @{ } # Define an aux. ordered hashtable
foreach ($keyValue in -split $_) { # Loop over key-value pairs
$key, $value = $keyValue -split '=', 2 # Split pair into key and value
$oht[$key] = $value -replace '^"|"$' # Add to hashtable with "..." removed
}
[pscustomobject] $oht # Convert to custom object and output.
}
}

注意:
  • 上面的假定您的值没有嵌入的空间;如果这样做,则需要做更多工作-请参阅下一节。
  • 要捕获变量中生成的自定义对象,只需使用$objects = switch ...
  • 在两个或两个以上的日志行中,$objects成为[object[]]实例的[pscustomobject]数组。如果要确保即使只有一条日志行,$objects也会变成数组,请使用[array] $objects = switch ...([array]实际上与[object[]]相同)。
  • 要将输出对象通过管道直接发送到其他cmdlet,请将switch语句括在& { ... }


  • 使用样本输入,将产生:

    date       srcip   destip  srcintf
    ---- ----- ------ -------
    2019-12-02 8.8.8.8 8.8.4.4 port2
    2019-12-01 8.8.8.8 8.8.4.4 port2
    2019-12-03 8.8.8.8 8.8.4.4 port2
    2019-12-05 8.8.8.8 8.8.4.4 port2
    2019-12-07 8.8.8.8 8.8.4.4 port2

    变体,支持在"..." (例如 srcintf="port 2")内带有嵌入式空格的值:
    switch -file .\testfile.log {
    default {
    $oht = [ordered] @{ }
    foreach ($keyValue in $_ -split '(\w+=(?:[^"][^ ]*|"[^"]*"))' -notmatch '^\s*$') {
    $key, $value = $keyValue -split '=', 2
    $oht[$key] = $value -replace '^"|"$'
    }
    [pscustomobject] $oht
    }
    }

    请注意,不支持嵌入式转义的 "实例(例如 srcintf="port \"2\""将不起作用)。

    说明:
  • $_ -split '(\w+=(?:[^"][^ ]*|"[^"]*"))'被匹配key=valueWithoutSpaceskey="value that may have spaces" token 的regex分割,并通过将表达式括在(...)中(创建捕获组),将这些“分隔符”包括在-split输出的 token 中(默认情况下不包括分隔符) 。
  • 然后,
  • -notmatch '^\s*$'从结果中清除空标记和全空格标记(“数据标记”,在我们的情况下不感兴趣),仅留下键值对。
  • $key, $value = $keyValue -split '=', 2通过=将给定的键值 token 最多分为2个 token ,并使用解构分配将键和值分配给单独的变量。
  • $oht[$key] = $value -replace '^"|"$'向aux添加一个条目。带有键和值的哈希表,其中-replace '^"|"$'使用 -replace operator从值的开头和结尾(如果存在)中删除"


  • [1] switch -File是一种灵活且速度更快的替代方法,可以结合使用 Get-ContentForEach-Object逐行处理文件。

    关于powershell - 如何使用Powershell转换文件内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59139169/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com