在 PowerShell 中更改多个文本文件中的日期格式

Change date format in multiple text files in PowerShell

我在一个目录中有大约 5000 个文本文件 (CSV)。文件以逗号分隔。我正在尝试将日期格式(它存储在每个文件的第一列中)从 M/d/yyyy 更改为 MM/dd/yyyy。

这 5000 个文件中大约有 100 万行,所以我认为 StreamWriter 命令是一种可行的方法。一些 CSV 文件有 header,但不是全部。请看下面的代码。我觉得我很接近...

下面的代码对一个特定文件 (test.csv) 起作用,但它不适用于单个目录中的所有 CSV 文件 (*.csv) 文件。是否还有更多space可以提高此代码的速度?

$file = "C:\Test\Test.csv";

try
{
    $stringBuilder = New-Object System.Text.StringBuilder;

    try
    {
        $reader = New-Object System.IO.StreamReader($file)

        while($reader.Peek() -ge 0)
        {
            [datetime]$dirDate = New-Object DateTime;
            $line = $reader.ReadLine();
            $dateVal = $line.Split(",")[0];

            if ([DateTime]::TryParseExact($dateVal,
                                          "M/d/yyyy",
                                          [System.Globalization.CultureInfo]::InvariantCulture,
                                          [System.Globalization.DateTimeStyles]::None,
                                          [ref]$dirDate))
            {
                $result = $line -replace $line.Substring(0, $line.IndexOf(",")), $dirDate.ToString("MM/dd/yyyy");
                $stringBuilder.Append($result + "`r`n") | Out-Null;
            }
            else
            {
                $stringBuilder.Append($line + "`r`n") | Out-Null;
            }
        }
    }
    finally
    {
        $reader.Close();
    }

    try
    {
        $sw = New-Object System.IO.StreamWriter $file;
        $sw.Write($stringBuilder.ToString());
        Write-Host "File processed successfully.";
    }
    finally
    {
        $sw.Close();
    }
}
catch
{
    Write-Host "Caught an exception:" -ForegroundColor Red;
    Write-Host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red;
    Write-Host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red;
}

没有 header 的文件示例:

 8/1/2014,35,35.6,32.64,34.17,4217150
 8/4/2014,34.34,35.86,33.66,34.17,2231804
 8/5/2014,33.74,34.08,33.11,33.58,3456364
 8/6/2014,33.91,35.08,33.76,33.92,2805103
 8/7/2014,33.8,34.99,33.01,33.43,2474410
 8/8/2014,33.23,34.19,32.5,33.76,1929437

文件示例 Header:

 Date,Header2,Header3,Header4,Header5,Header6
 8/1/2014,75.65,78,74.21,76.7,1376428
 8/4/2014,77.07,81.459,76.92,80.96,1871618
 8/5/2014,80.87,82.5,78.101,79.34,1894376
 8/6/2014,78.42,83.49,77.99,82.75,2792467
 8/7/2014,81.27,86,78.82,85.8,4496068

我把它转换成函数给你了。你真的很接近,但在 try catch finally 阻塞时遇到了一些问题。我还将 $reader.peek -ge 0 更改为 -not $reader.endofstream

function ParseCSV ($file) {
    try {
        $stringBuilder = New-Object System.Text.StringBuilder;
        $reader = New-Object System.IO.StreamReader($file)
        while(-not $reader.EndOfStream) {
            [datetime]$dirDate = New-Object DateTime;
            $line = $reader.ReadLine();
            $dateVal = $line.Split(",")[0];
            if([DateTime]::TryParseExact($dateVal,
                                         "M/d/yyyy",
                                         [System.Globalization.CultureInfo]::InvariantCulture,
                                         [System.Globalization.DateTimeStyles]::None,
                                         [ref]$dirDate))
            {
                $result = $line -replace $line.Substring(0, $line.IndexOf(",")), $dirDate.ToString("MM/dd/yyyy");
                $stringBuilder.Append($result + "`r`n") | Out-Null;
            }
            else
            {
                $stringBuilder.Append($line + "`r`n") | Out-Null;
            }
        }
        $reader.Close()
        $sw = New-Object System.IO.StreamWriter $file;
        $sw.Write($stringBuilder.ToString());
        Write-Host "File processed successfully.";
    }
    catch {
        Write-Host "Caught an exception:" -ForegroundColor Red;
        Write-Host "Exception Type: $($_.Exception.GetType().FullName)" -ForegroundColor Red;
        Write-Host "Exception Message: $($_.Exception.Message)" -ForegroundColor Red;
    }
    finally {
        if($reader) {
            $reader.Dispose()
        }
        if($sw) {
            $sw.Dispose()
        }
    }
}

我是这样使用的:

dir *.csv | %{ParseCSV $_.FullName}

它解析了您提供的 25 个示例文件,将日期从 m/d/yyyy 转换为 mm/dd/yyyy。