Files
Docker7530 7f14056210 1778682052
2026-05-13 22:20:54 +08:00

2.6 KiB

param(
    [Parameter(Mandatory = $true, Position = 0)]
    [string]$InputFile,

    [Parameter(Mandatory = $true, Position = 1)]
    [string]$Domain,

    [Parameter(Position = 2)]
    [string]$OutputFile,

    [switch]$MatchAnywhere
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Resolve-LogPath {
    param([string]$Path)

    if (Test-Path -LiteralPath $Path -PathType Leaf) {
        return (Resolve-Path -LiteralPath $Path).Path
    }

    if ([System.IO.Path]::GetExtension($Path) -eq '') {
        $pathWithLogExtension = "$Path.log"
        if (Test-Path -LiteralPath $pathWithLogExtension -PathType Leaf) {
            return (Resolve-Path -LiteralPath $pathWithLogExtension).Path
        }
    }

    throw "Input file not found: $Path"
}

function Test-CdnLogDomain {
    param(
        [string]$Line,
        [string]$ExpectedDomain
    )

    $firstTab = $Line.IndexOf("`t")
    if ($firstTab -lt 0) { return $false }

    $secondTab = $Line.IndexOf("`t", $firstTab + 1)
    if ($secondTab -lt 0) { return $false }

    $thirdTab = $Line.IndexOf("`t", $secondTab + 1)
    if ($thirdTab -lt 0) { return $false }

    $fourthTab = $Line.IndexOf("`t", $thirdTab + 1)
    if ($fourthTab -lt 0) { return $false }

    $lineDomain = $Line.Substring($thirdTab + 1, $fourthTab - $thirdTab - 1)
    return [string]::Equals($lineDomain, $ExpectedDomain, [System.StringComparison]::OrdinalIgnoreCase)
}

$resolvedInputFile = Resolve-LogPath -Path $InputFile
$inputDirectory = Split-Path -Parent $resolvedInputFile
$inputBaseName = [System.IO.Path]::GetFileNameWithoutExtension($resolvedInputFile)

if ([string]::IsNullOrWhiteSpace($OutputFile)) {
    $OutputFile = Join-Path $inputDirectory "$inputBaseName`_$Domain"
}

$reader = [System.IO.StreamReader]::new($resolvedInputFile)
$writerEncoding = [System.Text.UTF8Encoding]::new($false)
$writer = [System.IO.StreamWriter]::new($OutputFile, $false, $writerEncoding)

$totalCount = 0L
$matchedCount = 0L

try {
    while (($line = $reader.ReadLine()) -ne $null) {
        $totalCount++

        if ($MatchAnywhere) {
            $matched = $line.IndexOf($Domain, [System.StringComparison]::OrdinalIgnoreCase) -ge 0
        }
        else {
            $matched = Test-CdnLogDomain -Line $line -ExpectedDomain $Domain
        }

        if ($matched) {
            $writer.WriteLine($line)
            $matchedCount++
        }
    }
}
finally {
    $writer.Dispose()
    $reader.Dispose()
}

Write-Host "Input file: $resolvedInputFile"
Write-Host "Output file: $OutputFile"
Write-Host "Total lines: $totalCount"
Write-Host "Matched lines: $matchedCount"