【问题标题】:Write Text file data to csv将文本文件数据写入 csv
【发布时间】:2021-10-01 16:12:24
【问题描述】:

以下是我在文本文件中的数据

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
  Volume 0     Z                       DVD-ROM         0 B  No Media           
  Volume 1         System Rese  NTFS   Partition    500 MB  Healthy    System  
  Volume 2     C   SYS          NTFS   Partition     99 GB  Healthy    Boot    
  Volume 3     S   SWAP         NTFS   Partition   6141 MB  Healthy    Pagefile
  Volume 4     D   DATA         NTFS   Partition    199 GB  Healthy            
  Volume 5     E   bit locker   NTFS   Partition      9 GB  Healthy            
  Volume 6     F   test         NTFS   Partition     10 GB  Healthy            

我必须把它写成 csv。尝试了下面的代码,但无法处理 Blank 值。例如对于第一行 Label,Fs,Info 值为空白

$data = get-content -Path "C:\d.txt"

$result = switch -Regex ($data) {
    '^\s*Volume \d'  {
        $disk,$status,$Label,$Fs,$Type,$size,$Stat,$Info = $_.Trim() -split '\s{2,}'

        [PsCustomObject]@{        
           'Server'   = $server
           'Volume ###' = $disk           
           'Ltr'   = $status
           'Label' = $Label
           'Fs'   = $Fs
           'Type' = $Type
           'Size'     = $size
           'Status' = $Stat
           'Info' = $Info
           
        }
    }
}

# output on console screen
$result | Format-Table -AutoSize

# output to CSV file
$result | Export-Csv -Path "C:\$server.csv" -NoTypeInformation -Append

输出就像

Server          Volume ### Ltr         Label      Fs        Type      Size    Status  Info    
------          ---------- ---         -----      --        ----      ----    ------  ----    
AxxxxxxxxxxxxxP Volume 0   Z           DVD-ROM    0 B       No Media                          
AxxxxxxxxxxxxxP Volume 1   System Rese NTFS       Partition 500 MB    Healthy System          
AxxxxxxxxxxxxxP Volume 2   C           SYS        NTFS      Partition 99 GB   Healthy Boot    
AxxxxxxxxxxxxxP Volume 3   S           SWAP       NTFS      Partition 6141 MB Healthy Pagefile
AxxxxxxxxxxxxxP Volume 4   D           DATA       NTFS      Partition 199 GB  Healthy         
AxxxxxxxxxxxxxP Volume 5   E           bit locker NTFS      Partition 9 GB    Healthy         
AxxxxxxxxxxxxxP Volume 6   F           test       NTFS      Partition 10 GB   Healthy         

请告诉我如何处理空格或我可以将其写入 csv 的任何其他方式

执行@Mathias 代码后

"Count","IsReadOnly","Keys","Values","IsFixedSize","SyncRoot","IsSynchronized"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"
"9","False","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","System.Collections.Specialized.OrderedDictionary+OrderedDictionaryKeyValueCollection","False","System.Object","False"

这就是我想要做的事情


$server = $env:COMPUTERNAME

# Start by reading in the table
# Replace this statement with `
$lines = Get-Content "c:\d.txt"
$lines = $lines -split '\r?\n'

# Assign the first two lines to separate variables
$header, $guardRails, $lines = $lines

# Split the header into individual column names
$columnNames = @(
  $header.Trim() -split '\s{2,}' |ForEach-Object Trim
)

# Use regex to match all the individual `---` sequences, grab their offset + length
$columnOffsets = @(
  [regex]::Matches($guardRails, '(?<!-)-+(?!-)') |Select Index,Length
)

# Parse the data based on the offsets located above
foreach($line in $lines){
  # Prepare a dictionary to hold the column values, add the Server property straight away
  $properties = [ordered]@{
    Server = $server
  }

  # Now we just need to iterate over the lists of column headers and extract the corresponding substring from the line
  for($i = 0; $i -lt $columnNames.Length; $i++){
    # Grab the column name and offset
    $propertyName = $columnNames[$i]
    $offset = $columnOffsets[$i]

    # Grab the substring corresponding to the column
    $propertyValue = $line.Substring($offset.Index, $offset.Length).Trim()

    # Add the information to our property dictionary
    $properties[$propertyName] = $propertyValue
  }

  # Output a new object based on the properties we grabbed from the column data
  [pscustomobject]$properties


# output on console screen
$properties | Format-Table -AutoSize

# output to CSV file
$properties | Export-Csv -Path "C:\$server.csv" -NoTypeInformation -Append

}

【问题讨论】:

  • 文件与您显示的完全一样吗?使用未对齐的标题?
  • 那是粘贴数据的时候

标签: powershell csv fixed-width


【解决方案1】:

使用标题下方的行 ( ---------- --- -----------...) 来检测在哪些偏移量处解析特定列名的数据:

# Start by reading in the table
# Replace this statement with `$lines = Get-Content .\path\to\file.txt` in your script
$lines = @'
  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ----------  ---  -----------  -----  ----------  -------  ---------  --------
  Volume 0     Z                       DVD-ROM         0 B  No Media           
  Volume 1         System Rese  NTFS   Partition    500 MB  Healthy    System  
  Volume 2     C   SYS          NTFS   Partition     99 GB  Healthy    Boot    
  Volume 3     S   SWAP         NTFS   Partition   6141 MB  Healthy    Pagefile
  Volume 4     D   DATA         NTFS   Partition    199 GB  Healthy            
  Volume 5     E   bit locker   NTFS   Partition      9 GB  Healthy            
  Volume 6     F   test         NTFS   Partition     10 GB  Healthy            
'@ -split '\r?\n'

# Assign the first two lines to separate variables
$header, $guardRails, $lines = $lines

# Split the header into individual column names
$columnNames = @(
  $header.Trim() -split '\s{2,}' |ForEach-Object Trim
)

# Use regex to match all the individual `---` sequences, grab their offset + length
$columnOffsets = @(
  [regex]::Matches($guardRails, '(?<!-)-+(?!-)') |Select Index,Length
)

# Parse the data based on the offsets located above
$volumeInfo = foreach($line in $lines){
  # Prepare a dictionary to hold the column values, add the Server property straight away
  $properties = [ordered]@{
    Server = 'Server123'
  }

  # Now we just need to iterate over the lists of column headers and extract the corresponding substring from the line
  for($i = 0; $i -lt $columnNames.Length; $i++){
    # Grab the column name and offset
    $propertyName = $columnNames[$i]
    $offset = $columnOffsets[$i]

    # Grab the substring corresponding to the column
    $propertyValue = $line.Substring($offset.Index, $offset.Length).Trim()

    # Add the information to our property dictionary
    $properties[$propertyName] = $propertyValue
  }

  # Output a new object based on the properties we grabbed from the column data
  [pscustomobject]$properties
}

$volumeInfo |Export-Csv path\to\output.csv -NoTypeInformation

【讨论】:

  • 感谢 Mathias 的回答。我试图将$properties 放在 csv 中,但没有得到值。用输出更新了我的答案。你能帮帮忙吗
  • @EmptyCoder 不要导出$properties - 从$properties 创建对象,然后将这些对象导出到CSV
  • 我不明白。你能给我一些样品吗
  • @EmptyCoder 我已经更新了答案中的代码
  • 这是您要导出的表达式[pscustomobject]$properties 的输出
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-21
  • 2015-04-28
  • 2017-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多