84 lines
No EOL
2.3 KiB
PowerShell
84 lines
No EOL
2.3 KiB
PowerShell
#Requires -Version 7.0
|
|
[CmdletBinding()]
|
|
param
|
|
(
|
|
[Parameter(Mandatory = $true, Position = 0)]
|
|
[string] $Directory,
|
|
|
|
# Treat the first line as a header and keep it in place while sorting the
|
|
# remaining rows. Set to $false for headerless files.
|
|
[bool] $HasHeader = $true
|
|
)
|
|
|
|
if (-not (Test-Path -LiteralPath $Directory -PathType Container))
|
|
{
|
|
throw "Directory not found: $Directory"
|
|
}
|
|
|
|
# Matches a trailing "_<14 digits>" immediately before a mandatory file extension.
|
|
$timestampPattern = '^(?<stem>.*)_\d{14}(?<ext>\.[^.\\/]+)$'
|
|
|
|
$utf8NoBom = [System.Text.UTF8Encoding]::new($false) # $false => no BOM
|
|
|
|
$csvFiles = Get-ChildItem -LiteralPath $Directory -Filter "*.csv" -File
|
|
|
|
if ($csvFiles.Count -eq 0)
|
|
{
|
|
Write-Warning "No .csv files found in: $Directory"
|
|
return
|
|
}
|
|
|
|
foreach ($file in $csvFiles)
|
|
{
|
|
$fileName = $file.Name
|
|
|
|
$match = [regex]::Match($fileName, $timestampPattern)
|
|
if (-not $match.Success)
|
|
{
|
|
Write-Warning "No timestamp pattern found, skipping: $fileName"
|
|
continue
|
|
}
|
|
|
|
$newName = $match.Groups['stem'].Value + $match.Groups['ext'].Value
|
|
$newPath = Join-Path $file.DirectoryName $newName
|
|
|
|
if ($newPath -ieq $file.FullName)
|
|
{
|
|
Write-Warning "Target name equals source, skipping: $fileName"
|
|
continue
|
|
}
|
|
|
|
# Read as an array of lines. Get-Content splits on the file's line breaks;
|
|
# this normalises the output to the platform newline on write-out.
|
|
$lines = @(Get-Content -LiteralPath $file.FullName)
|
|
|
|
if ($lines.Count -eq 0)
|
|
{
|
|
Write-Warning "File is empty, writing as-is: $fileName"
|
|
$sorted = $lines
|
|
}
|
|
elseif ($HasHeader)
|
|
{
|
|
# Keep line 0 (header) fixed, sort the rest ordinally.
|
|
$header = $lines[0]
|
|
$dataLines = if ($lines.Count -gt 1)
|
|
{
|
|
$lines[1..($lines.Count - 1)]
|
|
}
|
|
else
|
|
{
|
|
@()
|
|
}
|
|
$sorted = @($header) + @($dataLines | Sort-Object -CaseSensitive)
|
|
}
|
|
else
|
|
{
|
|
$sorted = @($lines | Sort-Object -CaseSensitive)
|
|
}
|
|
|
|
# Join with LF and terminate with a trailing newline.
|
|
$content = ($sorted -join "`n") + "`n"
|
|
|
|
[System.IO.File]::WriteAllText($newPath, $content, $utf8NoBom)
|
|
Write-Output "Wrote: $newPath ($($sorted.Count) lines)"
|
|
} |