使用Windows cmd或Powershell将多行文本日志转换为CSV

时间:2017-10-01 05:06:01

标签: windows powershell cmd

我试图将统一的多行日志文件转换为CSV,但没有任何效果。请帮忙!我在Windows服务器上,所以它必须是命令行或Powershell。

输入样本:

SERVICE_NAME: BDESVC
DISPLAY_NAME: BitLocker Drive Encryption Service
BDESVC hosts the BitLocker Drive Encryption service. BitLocker Drive Encryption provides secure startup for the operating system, as well as full volume encryption for OS, fixed or removable volumes. This service allows BitLocker to prompt users for various actions related to their volumes when mounted, and unlocks volumes automatically without user interaction. Additionally, it stores recovery information to Active Directory, if available, and, if necessary, ensures the most recent recovery certificates are used.  Stopping or disabling the service would prevent users from leveraging this functionality.
    TYPE          : 20 WIN32_SHARE_PROCESS 
    START_TYPE    : 3  DEMAND_START
    ERROR_CONTROL     : 1  NORMAL
    BINARY_PATH_NAME  : C:\WINDOWS\System32\svchost.exe -k netsvcs
    LOAD_ORDER_GROUP  : 
    TAG       : 0
    DEPENDENCIES      : 
    SERVICE_START_NAME: localSystem
    FAIL_RESET_PERIOD : 900 seconds
    FAILURE_ACTIONS   : Restart DELAY: 60000 seconds
              : Restart DELAY: 60000 seconds
              : None    DELAY: 0 seconds

SERVICE_NAME: BFE
DISPLAY_NAME: Base Filtering Engine
The Base Filtering Engine (BFE) is a service that manages firewall and Internet Protocol security (IPsec) policies and implements user mode filtering. Stopping or disabling the BFE service will significantly reduce the security of the system. It will also result in unpredictable behavior in IPsec management and firewall applications.
    TYPE          : 20 WIN32_SHARE_PROCESS 
    START_TYPE    : 2  AUTO_START
    ERROR_CONTROL     : 1  NORMAL
    BINARY_PATH_NAME  : C:\WINDOWS\system32\svchost.exe -k LocalServiceNoNetwork
    LOAD_ORDER_GROUP  : NetworkProvider
    TAG       : 0
    DEPENDENCIES      : RpcSs
    SERVICE_START_NAME: NT AUTHORITY\LocalService
    FAIL_RESET_PERIOD : 86400 seconds
    FAILURE_ACTIONS   : Restart DELAY: 120000 seconds
              : Restart DELAY: 300000 seconds
              : None    DELAY: 0 seconds

需要CSV输出(仅显示第一个事件):

SERVICE_NAME,DISPLAY_NAME,DESCRIPTION,TYPE,START_TYPE,ERROR_CONTROL,BINARY_PATH_NAME,LOAD_ORDER_GROUP,TAG,DEPENDENCIES,SERVICE_START_NAME,FAIL_RESET_PERIOD,FAILURE_ACTIONS_1,FAILURE_ACTIONS_2,FAILURE_ACTIONS_3,
BDESVC,BitLocker Drive Encryption Service,"BDESVC hosts the BitLocker Drive Encryption service. BitLocker Drive Encryption provides secure startup for the operating system, as well as full volume encryption for OS, fixed or removable volumes. This service allows BitLocker to prompt users for various actions related to their volumes when mounted, and unlocks volumes automatically without user interaction. Additionally, it stores recovery information to Active Directory, if available, and, if necessary, ensures the most recent recovery certificates are used.  Stopping or disabling the service would prevent users from leveraging this functionality.",20 WIN32_SHARE_PROCESS,3  DEMAND_START,1  NORMAL,C:\WINDOWS\System32\svchost.exe -k netsvcs,,0,,localSystem,900 seconds,Restart  DELAY: 60000 seconds,Restart    DELAY: 60000 seconds,None   DELAY: 0 seconds,

2 个答案:

答案 0 :(得分:0)

这是一个可能的解决方案。请记住,这会对您的数据做出一些假设,并且做这种事情总是有点笨拙:

(Get-Content 'YourFile.log') -Replace '(.*?)\s*:\s*(.*)','$1=$2' -Split '\r\n\r\n' | ForEach-Object { 
    $Text = ($_ -split '\n') -Replace '\\','\\'
    $Text[2] = 'DESCRIPTION='+ $Text[2]
    $Result = $Text | Out-String | ConvertFrom-StringData
    $Properties = [ordered]@{}

    $Headers = 'SERVICE_NAME','DISPLAY_NAME','DESCRIPTION','TYPE','START_TYPE','ERROR_CONTROL','BINARY_PATH_NAME','LOAD_ORDER_GROUP','TAG','DEPENDENCIES','SERVICE_START_NAME','FAIL_RESET_PERIOD','FAILURE_ACTIONS'
    $Headers | ForEach-Object { $Properties.Add($_,$Result.$_) }
    [PSCustomObject]$Properties

} | Export-CSV 'out.csv' -NoTypeInformation
  • 使用正则表达式(.*?)\s*:\s*(.*)将第一个:及其任意一侧的空格字符转换为=。我们这样做是为了以后可以使用ConvertFrom-StringData cmdlet将数据转换为哈希表对象。
  • 根据有两个(Windows样式)回车符\r\n\r\n的位置拆分数据,以便我们收集各个记录
  • 遍历记录并将文本拆分为单独的行。使用(令人困惑的)正则表达式'\\','\\'替换任意带有两个斜杠的斜杠。这样,ConvertFrom-StringData不会被文件路径绊倒。
  • 取数据中的第三行并将'DESCRIPTION ='添加到此行的开头,否则此行不是预期的name = value格式。
  • 通过Out-String将结果文本返回到单个字符串对象,然后通过ConvertFrom-StringData将其转换为哈希表。
  • 由于ConvertFrom-StringData按字母顺序重新排序字段,因此会创建名为[ordered]的第二个$Properties哈希表,该哈希表使用预定义的有序标头列表,然后从中创建PowerShell对象。
  • 将结果导出为CSV。

答案 1 :(得分:0)

要提供与Mark Wragg不同的视角,您可以尝试使用Select-String来捕获需要输出的变量,而不是完全按照这两种特定情况处理格式。< / p>

您可以尝试这样的事情:

$myArr = [IO.File]::ReadAllText("C:\YourLogFile.txt") | Select-String -Pattern "SERVICE_NAME[\s\S]*?(?=SERVICE_NAME)" -AllMatches | % {$_.Matches} | % {$_.Value}

这将返回所有单个日志条目的数组,基于SERVICE_NAME开始每个条目的假设。从那里,您可以循环遍历该数组中的每个条目,并查找要输出到CSV的值:

$myArr = @()
[IO.File]::ReadAllText("C:\YourLogFile.txt") | Select-String -Pattern "SERVICE_NAME[\s\S]*?(?=(SERVICE_NAME)|($))" -AllMatches | % {$_.Matches} | % {$_.Value} | % { $myArr += `
    [PSCustomObject]@{
        "Type" = Select-String -InputObject $_ -Pattern "(?<=TYPE          : ).*?(?=\r)" | % {$_.Matches} | % {$_.Value};
        "START_TYPE" = Select-String -InputObject $_ -Pattern "(?<=START_TYPE    : ).*?(?=\r)" | % {$_.Matches} | % {$_.Value};
    }}

您可以根据需要在该哈希表中添加任意数量的属性(ERROR_CONTROL,SERVICE_START_NAME等),然后使用`Export-CSV&#39;将它们写入文件。基于此解决方案,有两种方法可以处理:

$myArr | Select-Object Type,Start_Type | Export-CSV 'out.csv' -NoTypeInformation

或将其添加到管道的末尾,如果您不小心将其读入变量:

[IO.File]::ReadAllText("C:\YourLogFile.txt") | Select-String -Pattern "SERVICE_NAME[\s\S]*?(?=(SERVICE_NAME)|($))" -AllMatches | % {$_.Matches} | % {$_.Value} | % { `
    @([PSCustomObject]@{
        "Type" = Select-String -InputObject $_ -Pattern "(?<=TYPE          : ).*?(?=\r)" | % {$_.Matches} | % {$_.Value};
        "START_TYPE" = Select-String -InputObject $_ -Pattern "(?<=START_TYPE    : ).*?(?=\r)" | % {$_.Matches} | % {$_.Value};
    })} | Select-Object -Property Type,Start_Type | Export-Csv -Path C:\temp\test\myout.txt -NoTypeInformation

请务必将要导出的所有属性添加到Select-Object