【问题标题】:Assistance Splitting Column Data into Multiple Columns from Import-CSV协助将列数据从 Import-CSV 拆分为多列
【发布时间】:2019-05-20 10:25:55
【问题描述】:

我使用 import-csv 命令导入 CSV:

$P = Import-Csv "C:\MyCSV.csv"

然后我运行“Get-Member”:

$P | Get-Member

输出:

名称 MemberType 定义 ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode 方法 int GetHashCode() GetType 方法类型 GetType() ToString 方法字符串 ToS​​tring() 消息注释属性字符串消息=ABC 1234 DEFGH 123:3212 IJKLM NOPQRST 23\13\19 ABC1234 0978AJD

然后我运行“格式表”:

$P | Format-Table

输出:

信息 -------- ABC 1234 DEFGH 123:3222 IJKNM NOPQRHT 23\13\19 ABC1234 0978AJD... BAC 3214 DEFAH 123:3422 IJFLM NOPQRAT 23\13\18 ABC1234 0978AJD... CEC 1534 DEFIH 123:3312 IJALM NOPQRFT 23\13\17 ABC1234 0978AJD... 3BC 1144 DAFGH 123:3612 IJZLM NOPQRGT 23\13\16 ABC1234 0978AJD...

我想通过用空格分隔来进一步分割这个输出。我不关心正确命名每个新列。我只是希望能够选择特定文本所属的任何列标题并将该输出导出到新的 CSV。

理想输出:

列 1 列 2 列 3 列 4 等 -------- ------- -------- -------- ABC 1234 DEFGH 123:3222 等

所以我可以运行如下命令:

select Column5,Column8

或类似的命令

select Column15,Column58

谁能帮我解决这个问题?

【问题讨论】:

  • 你能提供一个你输入的样例吗?我怀疑您可以更有效地使用 Import-CSV,但我无法通过提供的信息来判断。
  • 您确定每一行都有相同数量的空格(因此,相同的列数)吗?
  • 是的,这些实际上是具有固定格式的 Windows 安全事件日志。

标签: powershell


【解决方案1】:

这应该可以完成工作:

# fake reading in a CSV file as text
#    in real life, use Get-Content
$InStuff = @'
Message
ABC 1234 DEFGH 123:3222 IJKNM NOPQRHT 23\13\19 ABC1234 0978AJD
BAC 3214 DEFAH 123:3422 IJFLM NOPQRAT 23\13\18 ABC1234 0978AJD
CEC 1534 DEFIH 123:3312 IJALM NOPQRFT 23\13\17 ABC1234 0978AJD
3BC 1144 DAFGH 123:3612 IJZLM NOPQRGT 23\13\16 ABC1234 0978AJD
'@ -split [environment]::NewLine

$ColCount = $InStuff[1].Split(' ').Count

$Collection = $InStuff |
    Select-Object -Skip 1 |
    ConvertFrom-Csv -Delimiter ' ' -Header (1..$ColCount).ForEach({"Column_$_"})

$Collection |
    Select-Object -Property 'Column_3', 'Column_7'

输出:

列_3 列_7 -------- -------- DEFGH 23\13\19 德法 23\13\18 DEFIH 23\13\17 达夫 23\13\16

它的作用:

  • 将文件读取为文本文件,而不是 CSV 文件
  • 计算列数
  • 跳过第一行
  • 创建 CSV 导入
    • 将分隔符设置为<space>
    • 将标头设置为1..$ColCount的范围
  • 筛选所需列

【讨论】:

  • 改进建议:前置列以提高可读性(1..$ColCount|%{"Column$_"})
  • @TheIncorrigible1 - 酷!我现在就这么做... [grin]
  • 我看到的唯一缺陷是您假设每行具有相同的列数。如果 OP 不确定每行是否具有相同数量的列,您可能需要执行初始 $ColCount = $InStuff|%{$_.Split(' ').Count}|Measure-Object -Max |% Maximum
  • @TheMadTechnician - 你认为这可能吗?我同意这个想法是有道理的,但是当 OP 对它来说似乎相当新时,我不想过度复杂化代码......
  • 可能不太可能,但我想我会提一下以防万一。
【解决方案2】:

李,我目前无法编辑自己的帖子,因为我的声誉太低 -_-。因此,我将用您要求的信息回复帖子:

为了进一步了解,这是我当前不起作用的代码:

    $InStuff = Get-Content -Path 'MyCSV.csv'

    $ColCount = $InStuff[1].Split(' ').Count

    $Collection = $InStuff |
        Select-Object -Skip 1 |
        ConvertFrom-Csv -Delimiter ' ' -Header         (1..$ColCount).ForEach({"Column_$_"})

$Collection

输出。如您所见,除 Column_1 之外的所有列都是空的:

Column_1   : <134>Dec 13 13:50:23 10.137.119.42 MSWinEventLog 1 Security 123456789 
Thu Dec 13 13:50:23 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy625 N/A 
Success Audit mydc1.dy625.com Directory Service Access  An operation was performed on 
an object.    Subject :   Security ID:  S-123456  Account Name:  dy625 Account 
Domain:  MyCompany   Logon ID:  XXXXXXXX   Object:   Object Server:  DS   Object 
Type:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Object Name:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   
Handle ID:  0x0    Operation:   Operation Type:  Object Access   Accesses:  Write 
Property  Access Mask:  0x20   Properties:  Write Property {XXXX-XXXX-XXXXX}  {XXXX- 
XXXX-XXXXX} {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX}   Additional Information:   
Parameter 1:  -   Parameter 2:   123456
Column_2   : 
Column_3   : 
Column_4   : 
Column_5   : 
...
Column_1   : <134>Dec 13 13:50:18 10.137.119.42 MSWinEventLog 1 Security 123456789 
Thu Dec 13 13:50:18 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy626 N/A 
Success Audit mydc1.dy625.com Directory Service Access  An operation was performed on 
an object.    Subject :   Security ID:  S-123456  Account Name:  dy626 Account 
Domain:  MyCompany   Logon ID:  XXXXXXXX   Object:   Object Server:  DS   Object 
Type:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Object Name:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   
Handle ID:  0x0    Operation:   Operation Type:  Object Access   Accesses:  Write 
Property  Access Mask:  0x20   Properties:  Write Property {XXXX-XXXX-XXXXX}  {XXXX- 
XXXX-XXXXX} {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX}   Additional Information:   
Parameter 1:  -   Parameter 2:   123456
Column_2   : 
Column_3   : 
Column_4   : 
Column_5   : 
...
Column_1   : <134>Dec 13 13:50:14 10.137.118.22 MSWinEventLog 1 Security 123456789 
Thu Dec 13 13:50:14 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy627 N/A 
Success Audit mydc1.dy625.com Directory Service Access  An operation was performed on 
an object.    Subject :   Security ID:  S-123456  Account Name:  dy627 Account 
Domain:  MyCompany   Logon ID:  XXXXXXXX   Object:   Object Server:  DS   Object 
Type:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Object Name:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   
Handle ID:  0x0    Operation:   Operation Type:  Object Access   Accesses:  Write 
Property  Access Mask:  0x20   Properties:  Write Property {XXXX-XXXX-XXXXX}  {XXXX- 
XXXX-XXXXX} {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX}   Additional Information:   
Parameter 1:  -   Parameter 2:   123456
Column_2   : 
Column_3   : 
Column_4   : 
Column_5   : 

正如我之前所说,我认为问题在于我不知道如何使用更新的语法重新实现 '-split [environment]::NewLine' 命令。如你所见,它不见了。我认为这是问题的原因。

当我按照您的建议输入原始文本时,整个前 3 行,您的语法按预期正常工作。

$InStuff = @'
Message
<134>Dec 13 13:50:23 10.137.119.42 MSWinEventLog 1 Security 123456789 Thu Dec 13 13:50:23 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy625 N/A Success Audit mydc1.dy625.com Directory Service Access  An operation was performed on an object.    Subject :   Security ID:  S-123456  Account Name:  dy625 Account Domain:  MyCompany   Logon ID:  XXXXXXXX   Object:   Object Server:  DS   Object Type:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Object Name:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Handle ID:  0x0    Operation:   Operation Type:  Object Access   Accesses:  Write Property  Access Mask:  0x20   Properties:  Write Property {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX}   Additional Information:   Parameter 1:  -   Parameter 2:   123456
<134>Dec 13 13:50:18 10.137.119.42 MSWinEventLog 1 Security 123456789 Thu Dec 13 13:50:18 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy626 N/A Success Audit mydc1.dy625.com Directory Service Access  An operation was performed on an object.    Subject :   Security ID:  S-123456  Account Name:  dy626 Account Domain:  MyCompany   Logon ID:  XXXXXXXX   Object:   Object Server:  DS   Object Type:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Object Name:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Handle ID:  0x0    Operation:   Operation Type:  Object Access   Accesses:  Write Property  Access Mask:  0x20   Properties:  Write Property {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX}   Additional Information:   Parameter 1:  -   Parameter 2:   123456
<134>Dec 13 13:50:14 10.137.118.22 MSWinEventLog 1 Security 123456789 Thu Dec 13 13:50:14 2018 4662 Microsoft-Windows-Security-Auditing MyCompany\dy627 N/A Success Audit mydc1.dy625.com Directory Service Access  An operation was performed on an object.    Subject :   Security ID:  S-123456  Account Name:  dy627 Account Domain:  MyCompany   Logon ID:  XXXXXXXX   Object:   Object Server:  DS   Object Type:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Object Name:  %{XXXXXXXX-XXXXXXXX-XXXXXXXX}   Handle ID:  0x0    Operation:   Operation Type:  Object Access   Accesses:  Write Property  Access Mask:  0x20   Properties:  Write Property {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX} {XXXX-XXXX-XXXXX}  {XXXX-XXXX-XXXXX}   Additional Information:   Parameter 1:  -   Parameter 2:   123456
'@ -split [environment]::NewLine

    $ColCount = $InStuff[1].Split(' ').Count

   $Collection = $InStuff |
        Select-Object -Skip 1 |
        ConvertFrom-Csv -Delimiter ' ' -Header     
    (1..$ColCount).ForEach({"Column_$_"})

    $Collection |
        Select-Object -Property 'Column_3', 'Column_7'

输出:

$Collection |
    Select-Object -Property 'Column_3', 'Column_7'

Column_3 Column_7
-------- --------
13:50:23 Security
13:50:18 Security
13:50:14 Security

同样,我认为问题在于我不知道如何实现'-split [environment]::NewLine'command。

$InStuff = Get-Content -Path 'MyCSV.csv' -split [environment]::NewLine

错误:

Get-Content : A parameter cannot be found that matches parameter name 'split'.

无论如何,我希望这能阐明这个问题。

【讨论】:

  • 那是因为您的输入数据与您提供的演示数据完全不同。 [grin] 请只发布输入数据——最好是第一三行以提供一些变化——以进行实际测试。
  • Lee_Dailey 我想你已经明白我的错误了。你是对的 - 问题在于数据本身。查看我的输入数据后,似乎有些日志与其他日志略有不同,有些是“控制访问”日志,而另一些是“写入属性”日志。很抱歉带领您进行这场疯狂的追逐 - 我很确定这个案子现在可以解决了!
猜你喜欢
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2021-04-29
相关资源
最近更新 更多