如何获取第 1 行中的分隔符数量并将分隔符数量添加到行尾,然后使用 Powershell 另存为新文件

How to get number of delimiters in line 1 and adding the number of delimiters to the end of the line and then saving as a new file with Powershell

我想统计一个文件中第1行(row)1中所有的“,”,然后与之后的每一行进行比较,如果第1行的“,”少,则相差“, ” 在该行的末尾通过使用 Powershell 进入一个新文件。

如何创建缺少分隔符的新文件?

任何想法和帮助将不胜感激。

数据文件:

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9
1,2,3,4,5,6,7,8
1,2,3,4,5,6,7
1,2,3,4,5,6
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5
1,2,3,4
1,2,3
1,2

需要新数据文件:

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,
1,2,3,4,5,6,7,8,,
1,2,3,4,5,6,7,,,
1,2,3,4,5,6,,,,
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,,,,,
1,2,3,4,,,,,,
1,2,3,,,,,,,
1,2,,,,,,,,

这是我的脚本:

$file = 'C:\Test\File1.csv'    
$i = 1
$reader = [System.IO.File]::OpenText($file)
$line = $reader.ReadLine()
$reader.Close()
$delimiter = $line.Split(",").Count
$reader = [System.IO.File]::OpenText($file)
     try {
        for() {
            $line = $reader.ReadLine()
             if ($line -eq $null) { break }
         $c = $line.Split(",").Count
         if($c -ne $delimiter -and $i -ne ${lines})  {
            ($d = $delimiter - $c) 
            if($c -ne $delimiter) {
            $varline = $line + ",".PadRight($d, ",") 
            $line -replace $line, $varline

            
                
            Write-Host "Line number: $i"
            Write-Host "Delimiters in line: $c"
            Write-Host "Delimiters should be: $delimiter" 
            Write-Host "Difference: $d"
            Write-Host "New Line: $varline"
            } 
                 }
                 $i++
         } 
     } 
     finally {
        $reader.Close()
     }
Set-Content "C:\Test\TestMod.csv" -Value $varline

写主机输出:(仅用于测试目的,不需要

1
1,2,3,4,5,6,7,8,9,
Line number: 2
Delimiters in line: 9
Delimiters should be: 10
Difference: 1
New Line: 1,2,3,4,5,6,7,8,9,
2
1,2,3,4,5,6,7,8,,
Line number: 3
Delimiters in line: 8
Delimiters should be: 10
Difference: 2
New Line: 1,2,3,4,5,6,7,8,,
3
1,2,3,4,5,6,7,,,
Line number: 4
Delimiters in line: 7
Delimiters should be: 10
Difference: 3
New Line: 1,2,3,4,5,6,7,,,
4
1,2,3,4,5,6,,,,
Line number: 5
Delimiters in line: 6
Delimiters should be: 10
Difference: 4
New Line: 1,2,3,4,5,6,,,,
5
1,2,3,4,5,,,,,
Line number: 7
Delimiters in line: 5
Delimiters should be: 10
Difference: 5
New Line: 1,2,3,4,5,,,,,
6
1,2,3,4,,,,,,
Line number: 8
Delimiters in line: 4
Delimiters should be: 10
Difference: 6
New Line: 1,2,3,4,,,,,,
8
1,2,,,,,,,,
Line number: 10
Delimiters in line: 2
Delimiters should be: 10
Difference: 8
New Line: 1,2,,,,,,,,

您可以构建任意处理管道来修改文本文件中的每一行并将结果输出到新的文本文件,如下所示:

Get-Content $outputPath |ForEach-Object { <# process file content here #> } |Set-Content $outputPath

因为除了第一行之外的每一行的处理每次都包含相同的操作:

  • ,
  • 计算,的数量与第一行的计数
  • 的差值
  • 追加尾随 ,

...我们只需要两个变量 - 一个用于跟踪我们是否检查了第一行,另一个用于保存逗号数:

$inFile = 'C:\Test\File1.csv'
$outFile = 'C:\Test\output.csv'

$initialized = $false
$commaCount  = 0

Get-Content -LiteralPath $inFile |ForEach-Object {
  if(-not $initialized){
    # first line, let's just count the commas
    $commaCount = $_.Split(',').Length - 1
    $initialized = $true
  } else {
    # subsequent lines, calculate the difference in number of commas 
    $commaCountDiff = $commaCount - ($_.Split(',').Length - 1)
    if($commaCountDiff -gt 0){
      # and add missing ones 
      $_ = "${_}$(',' * $commaCountDiff)"
    }
  }

  # output the line (modified or not)
  $_
} |Set-Content -LiteralPath $outFile

您也可以通过将数据线循环两次来实现:

$data = Get-Content -Path 'C:\Test\File1.csv'
# first loop to get the maximum number of fields in the data
$maxFields = ($data | ForEach-Object {($_ -split ',').Count} | Measure-Object -Maximum).Maximum
# second loop to output the lines with extra commas (empty fields) appended
$data | ForEach-Object {
    $_ + ',' * ($maxFields - ($_ -split ',').Count)
} | Set-Content -Path 'C:\Test\TestMod.csv'

输出:

1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,6,7,8,9,
1,2,3,4,5,6,7,8,,
1,2,3,4,5,6,7,,,
1,2,3,4,5,6,,,,
1,2,3,4,5,6,7,8,9,10
1,2,3,4,5,,,,,
1,2,3,4,,,,,,
1,2,3,,,,,,,
1,2,,,,,,,,

非常感谢Mathias R. Jessen

这是对我有用的代码:

$inFile = 'C:\Test\File1.csv'
$outFile = 'C:\Test\output.csv'

$initialized = $false
$commaCount  = 0

Get-Content -LiteralPath $inFile |ForEach-Object {
  if(-not $initialized){
    # first line, let's just count the commas
    $commaCount = $_.Split(',').Length - 1
    $initialized = $true
  } else {
    # subsequent lines, calculate the difference in number of commas 
    $commaCountDiff = $commaCount - $_.Split(',').Length +1
    if($commaCountDiff -gt 0){
      # and add missing ones 
      $_ = "${_}$(',' * $commaCountDiff)"
    }
  }

  # output the line (modified or not)
  $_
} |Set-Content -LiteralPath $outFile