【问题标题】:Power Shell CSV conversionPowershell CSV 转换
【发布时间】:2018-11-15 15:22:35
【问题描述】:

您好,我正在尝试在 Powershell 中将文本文件导出为 csv 格式,但遇到一些对齐问题。数据未正确显示。

输入文字

clexec.py "top -d1|grep Swap"
NVA-0055-Prod-N08:Swap: 48G Total, 1428K Used, 48G Free
NVA-0055-Prod-N01:Swap: 48G Total, 332K Used, 48G Free
NVA-0055-Prod-N04:Swap: 48G Total, 169M Used, 48G Free
NVA-0055-Prod-N05:Swap: 48G Total, 884K Used, 48G Free
NVA-0055-Prod-N02:Swap: 48G Total, 4236K Used, 48G Free
NVA-0055-Prod-N06:Swap: 48G Total, 132K Used, 48G Free
NVA-0055-Prod-N07:Swap: 48G Total, 92K Used, 48G Free
NVA-0055-Prod-N03:Swap: 48G Total, 712K Used, 48G Free

我正在使用下面的命令

$a= import-csv 'C:\Users\PDC_AVERE_SWAP_OP.txt' -Delimiter 't' -Header 'Name','Total','used','free'
$a | export-csv csvfile.csv -NoTypeInformation

我的输出如下所示

在更正分隔符部分后,我将所有数据放在一个列中,但我需要将其拆分为 Total、used 和 free 列

【问题讨论】:

    标签: powershell csv


    【解决方案1】:

    问题是-Delimiter 't'。它的字面意思是字母t 是分隔符。您很可能是指制表符,在 Powershell 中是反引号:`t

    【讨论】:

      【解决方案2】:

      如果您想从文件中删除初始行,
      您可以将内容阅读为文本并跳过ConvertFrom-Csv之前的第一行

      Get-Content 'C:\Users\PDC_AVERE_SWAP_OP.txt' | Select-Object -Skip 1|
        ConvertFrom-Csv -Delimiter "`t" -Header Name,Total,used,free |
          Export-Csv csvfile.csv -NoTypeInformation
      

      以防万一没有制表符,而是上面示例中的空格,您可以使用

      $Data = Get-Content '.\PDC_AVERE_SWAP_OP.txt' |Select-Object -skip 1| ForEach-Object{
          $Name,$Total,$used,$free = ($_ -split('\s+'))[0,1,3,5]
          [PSCustomObject]@{
             Name = $Name
             Total= $Total
             used = $used
             free = $free
          }
      }
      $Data
      $Data | Export-Csv '.\PDC_AVERE_SWAP_OP.csv' -NoTypeInformation
      $Data | Export-Excel  '.\PDC_AVERE_SWAP_OP.xlsx' -AutoSize -Show
      

      从而从每个值中剥离标签:

      Name                    Total used  free
      ----                    ----- ----  ----
      NVA-0055-Prod-N08:Swap: 48G   1428K 48G
      NVA-0055-Prod-N01:Swap: 48G   332K  48G
      NVA-0055-Prod-N04:Swap: 48G   169M  48G
      NVA-0055-Prod-N05:Swap: 48G   884K  48G
      NVA-0055-Prod-N02:Swap: 48G   4236K 48G
      NVA-0055-Prod-N06:Swap: 48G   132K  48G
      NVA-0055-Prod-N07:Swap: 48G   92K   48G
      NVA-0055-Prod-N03:Swap: 48G   712K  48G
      

      使用Export-Excel会直接得到一个xlsx文件

      编辑:正如评论中提到的,这里使用正则表达式来分隔元素的变体 查看 RegEx 直播 https://regex101.com/r/GFXpXw/1 缺少使用的值

      ## Q:\Test\2018\11\15\SO_53322626_2.ps1
      
      $RE = "^(?<Name>[^ ]+) (?<Total>\d+[KMG]) Total(, (?<used>\d+[KMG]) Used)?, (?<free>\d+[KMG])"
      
      $Data = Get-Content '.\PDC_AVERE_SWAP_OP.txt' |Select-Object -skip 1| ForEach-Object{
          if ($_ -match $RE){
              [PSCustomObject]@{
                 Name = $Matches.Name
                 Total= $Matches.Total
                 used = $Matches.used
                 free = $Matches.free
              }
          } else {Write-Host ("{0} didn't match RegEx" -f $_)}
      }
      $Data
      $Data | Export-Csv '.\PDC_AVERE_SWAP_OP.csv' -NoTypeInformation
      #$Data | Export-Excel  '.\PDC_AVERE_SWAP_OP.xlsx' -AutoSize
      

      【讨论】:

      • 如果在某些情况下使用的列不存在,空闲列数据会移动到使用的列还是空白?
      • 如果没有按预期分隔数据的分隔符,值将向左滑动,这可以通过使用前瞻和命名捕获组的更复杂的正则表达式来避免(假设您使用的是第二个脚本)
      • 查看更改后的答案。
      【解决方案3】:

      使用“`t”而不是“t”作为分隔符,而不是使用Export-CSV,您可以使用以下代码,

       "Name,Total,used,free" | Set-Content csvfile.csv
      
       $a  |   %{ Write-Output "$($_.Name),$($_.Total),$($_.free),$($_.free)"  |  out-file csvfile.csv -Encoding  ascii  -Append  -Force   } 
      

      【讨论】:

      • 请编辑答案并解释为什么out-file 会比export-csv 更好。
      • 通常Out-File 会给你更多的灵活性和更多的控制权。考虑一个场景,脚本中有几个不同的变量,您需要从多个变量中选择一些属性并将输出导出到 CSV。在这种情况下,您不能使用 Export-CSV。现在提出您的问题,有时 Export-CSV 不像您的情况那样按预期工作(不知道确切原因)然后我们可以使用 Out-File 来获得更多控制权。@vonPryz
      猜你喜欢
      • 2015-08-09
      • 2017-09-09
      • 1970-01-01
      • 2015-08-23
      • 2022-01-15
      • 2021-10-10
      • 1970-01-01
      • 2017-10-19
      • 2021-03-31
      相关资源
      最近更新 更多