PowerShell サンプルコード
# Multi-Format File Comparison Script
# SVG, Excel, SQL, JSON ファイルの差分比較と詳細出力
function Compare-JsonFiles {
param(
[string]$File1,
[string]$File2
)
Write-Host "`n=== JSON比較: $([System.IO.Path]::GetFileName($File1)) vs $([System.IO.Path]::GetFileName($File2)) ===" -ForegroundColor Cyan
try {
$json1 = Get-Content $File1 -Raw | ConvertFrom-Json
$json2 = Get-Content $File2 -Raw | ConvertFrom-Json
$json1Str = $json1 | ConvertTo-Json -Depth 100 -Compress
$json2Str = $json2 | ConvertTo-Json -Depth 100 -Compress
if ($json1Str -eq $json2Str) {
Write-Host "差分なし" -ForegroundColor Green
return 0
}
# 行ごとの比較
$lines1 = ($json1 | ConvertTo-Json -Depth 100) -split "`n"
$lines2 = ($json2 | ConvertTo-Json -Depth 100) -split "`n"
$maxLines = [Math]::Max($lines1.Length, $lines2.Length)
$diffCount = 0
for ($i = 0; $i -lt $maxLines; $i++) {
$line1 = if ($i -lt $lines1.Length) { $lines1[$i].Trim() } else { "" }
$line2 = if ($i -lt $lines2.Length) { $lines2[$i].Trim() } else { "" }
if ($line1 -ne $line2) {
$diffCount++
Write-Host "行 $($i+1):" -ForegroundColor Yellow
Write-Host " File1: $line1" -ForegroundColor Red
Write-Host " File2: $line2" -ForegroundColor Green
}
}
Write-Host "総差分行数: $diffCount" -ForegroundColor Magenta
return $diffCount
}
catch {
Write-Host "JSON解析エラー: $($_.Exception.Message)" -ForegroundColor Red
return -1
}
}
function Compare-XmlFiles {
param(
[string]$File1,
[string]$File2
)
Write-Host "`n=== SVG/XML比較: $([System.IO.Path]::GetFileName($File1)) vs $([System.IO.Path]::GetFileName($File2)) ===" -ForegroundColor Cyan
try {
[xml]$xml1 = Get-Content $File1
[xml]$xml2 = Get-Content $File2
# 正規化されたXMLで比較
$xml1Str = $xml1.OuterXml
$xml2Str = $xml2.OuterXml
if ($xml1Str -eq $xml2Str) {
Write-Host "差分なし" -ForegroundColor Green
return 0
}
# 行ごとの比較
$lines1 = $xml1Str -split "`n"
$lines2 = $xml2Str -split "`n"
$maxLines = [Math]::Max($lines1.Length, $lines2.Length)
$diffCount = 0
for ($i = 0; $i -lt $maxLines; $i++) {
$line1 = if ($i -lt $lines1.Length) { $lines1[$i].Trim() } else { "" }
$line2 = if ($i -lt $lines2.Length) { $lines2[$i].Trim() } else { "" }
if ($line1 -ne $line2) {
$diffCount++
Write-Host "行 $($i+1):" -ForegroundColor Yellow
Write-Host " File1: $line1" -ForegroundColor Red
Write-Host " File2: $line2" -ForegroundColor Green
}
}
Write-Host "総差分行数: $diffCount" -ForegroundColor Magenta
return $diffCount
}
catch {
Write-Host "XML解析エラー: $($_.Exception.Message)" -ForegroundColor Red
return -1
}
}
function Compare-ExcelFiles {
param(
[string]$File1,
[string]$File2
)
Write-Host "`n=== Excel比較: $([System.IO.Path]::GetFileName($File1)) vs $([System.IO.Path]::GetFileName($File2)) ===" -ForegroundColor Cyan
try {
# ImportExcelモジュールの確認
if (-not (Get-Module -ListAvailable -Name ImportExcel)) {
Write-Host "ImportExcelモジュールが必要です。インストール: Install-Module -Name ImportExcel" -ForegroundColor Red
return -1
}
Import-Module ImportExcel
$excel1 = Import-Excel $File1
$excel2 = Import-Excel $File2
if ($excel1.Count -ne $excel2.Count) {
Write-Host "行数が異なります: File1($($excel1.Count)行) vs File2($($excel2.Count)行)" -ForegroundColor Yellow
}
$maxRows = [Math]::Max($excel1.Count, $excel2.Count)
$diffCount = 0
# 列名の取得
$columns1 = if ($excel1.Count -gt 0) { $excel1[0].PSObject.Properties.Name } else { @() }
$columns2 = if ($excel2.Count -gt 0) { $excel2[0].PSObject.Properties.Name } else { @() }
$allColumns = ($columns1 + $columns2) | Sort-Object -Unique
for ($i = 0; $i -lt $maxRows; $i++) {
$row1 = if ($i -lt $excel1.Count) { $excel1[$i] } else { $null }
$row2 = if ($i -lt $excel2.Count) { $excel2[$i] } else { $null }
$rowDiff = $false
foreach ($col in $allColumns) {
$val1 = if ($row1) { $row1.$col } else { "" }
$val2 = if ($row2) { $row2.$col } else { "" }
if ($val1 -ne $val2) {
if (-not $rowDiff) {
Write-Host "行 $($i+1) に差分:" -ForegroundColor Yellow
$rowDiff = $true
$diffCount++
}
Write-Host " 列 '$col': '$val1' vs '$val2'" -ForegroundColor White
}
}
}
if ($diffCount -eq 0) {
Write-Host "差分なし" -ForegroundColor Green
} else {
Write-Host "総差分行数: $diffCount" -ForegroundColor Magenta
}
return $diffCount
}
catch {
Write-Host "Excel読み込みエラー: $($_.Exception.Message)" -ForegroundColor Red
return -1
}
}
function Compare-SqlFiles {
param(
[string]$File1,
[string]$File2
)
Write-Host "`n=== SQL比較: $([System.IO.Path]::GetFileName($File1)) vs $([System.IO.Path]::GetFileName($File2)) ===" -ForegroundColor Cyan
try {
$sql1 = Get-Content $File1
$sql2 = Get-Content $File2
# 空行とコメント行を除外して比較
$sql1Clean = $sql1 | Where-Object { $_ -notmatch '^\s*$' -and $_ -notmatch '^\s*--' } | ForEach-Object { $_.Trim() }
$sql2Clean = $sql2 | Where-Object { $_ -notmatch '^\s*$' -and $_ -notmatch '^\s*--' } | ForEach-Object { $_.Trim() }
$maxLines = [Math]::Max($sql1Clean.Length, $sql2Clean.Length)
$diffCount = 0
for ($i = 0; $i -lt $maxLines; $i++) {
$line1 = if ($i -lt $sql1Clean.Length) { $sql1Clean[$i] } else { "" }
$line2 = if ($i -lt $sql2Clean.Length) { $sql2Clean[$i] } else { "" }
if ($line1 -ne $line2) {
$diffCount++
Write-Host "行 $($i+1):" -ForegroundColor Yellow
Write-Host " File1: $line1" -ForegroundColor Red
Write-Host " File2: $line2" -ForegroundColor Green
}
}
if ($diffCount -eq 0) {
Write-Host "差分なし" -ForegroundColor Green
} else {
Write-Host "総差分行数: $diffCount" -ForegroundColor Magenta
}
return $diffCount
}
catch {
Write-Host "SQL読み込みエラー: $($_.Exception.Message)" -ForegroundColor Red
return -1
}
}
function Compare-TextFiles {
param(
[string]$File1,
[string]$File2
)
Write-Host "`n=== テキスト比較: $([System.IO.Path]::GetFileName($File1)) vs $([System.IO.Path]::GetFileName($File2)) ===" -ForegroundColor Cyan
try {
$content1 = Get-Content $File1
$content2 = Get-Content $File2
$maxLines = [Math]::Max($content1.Length, $content2.Length)
$diffCount = 0
for ($i = 0; $i -lt $maxLines; $i++) {
$line1 = if ($i -lt $content1.Length) { $content1[$i] } else { "" }
$line2 = if ($i -lt $content2.Length) { $content2[$i] } else { "" }
if ($line1 -ne $line2) {
$diffCount++
Write-Host "行 $($i+1):" -ForegroundColor Yellow
Write-Host " File1: $line1" -ForegroundColor Red
Write-Host " File2: $line2" -ForegroundColor Green
}
}
if ($diffCount -eq 0) {
Write-Host "差分なし" -ForegroundColor Green
} else {
Write-Host "総差分行数: $diffCount" -ForegroundColor Magenta
}
return $diffCount
}
catch {
Write-Host "ファイル読み込みエラー: $($_.Exception.Message)" -ForegroundColor Red
return -1
}
}
function Compare-FilePair {
param(
[string]$File1,
[string]$File2
)
if (-not (Test-Path $File1)) {
Write-Host "ファイルが見つかりません: $File1" -ForegroundColor Red
return -1
}
if (-not (Test-Path $File2)) {
Write-Host "ファイルが見つかりません: $File2" -ForegroundColor Red
return -1
}
$ext1 = [System.IO.Path]::GetExtension($File1).ToLower()
$ext2 = [System.IO.Path]::GetExtension($File2).ToLower()
if ($ext1 -ne $ext2) {
Write-Host "異なる拡張子のファイルです: $ext1 vs $ext2" -ForegroundColor Yellow
}
switch ($ext1) {
".json" { return Compare-JsonFiles $File1 $File2 }
".svg" { return Compare-XmlFiles $File1 $File2 }
".xml" { return Compare-XmlFiles $File1 $File2 }
".xlsx" { return Compare-ExcelFiles $File1 $File2 }
".xls" { return Compare-ExcelFiles $File1 $File2 }
".sql" { return Compare-SqlFiles $File1 $File2 }
default { return Compare-TextFiles $File1 $File2 }
}
}
# メイン実行部分
function Main {
param(
[string]$Folder1,
[string]$Folder2,
[string]$OutputFile = ""
)
Write-Host "=== Multi-Format File Comparison ===" -ForegroundColor Green
Write-Host "フォルダ1: $Folder1"
Write-Host "フォルダ2: $Folder2"
Write-Host ""
if ($OutputFile) {
Start-Transcript -Path $OutputFile
}
$extensions = @("*.json", "*.svg", "*.xlsx", "*.xls", "*.sql")
$totalFiles = 0
$totalDifferences = 0
foreach ($ext in $extensions) {
Write-Host "`n" + "="*50 -ForegroundColor Blue
Write-Host "処理中: $ext ファイル" -ForegroundColor Blue
Write-Host "="*50 -ForegroundColor Blue
$files1 = Get-ChildItem -Path $Folder1 -Filter $ext -Recurse
foreach ($file1 in $files1) {
$relativePath = $file1.FullName.Substring($Folder1.Length + 1)
$file2Path = Join-Path $Folder2 $relativePath
if (Test-Path $file2Path) {
$totalFiles++
$diffCount = Compare-FilePair $file1.FullName $file2Path
if ($diffCount -gt 0) {
$totalDifferences += $diffCount
}
} else {
Write-Host "`n対応ファイルが見つかりません: $relativePath" -ForegroundColor Red
}
}
}
Write-Host "`n" + "="*60 -ForegroundColor Green
Write-Host "=== 最終結果 ===" -ForegroundColor Green
Write-Host "比較したファイル数: $totalFiles"
Write-Host "総差分箇所数: $totalDifferences"
Write-Host "="*60 -ForegroundColor Green
if ($OutputFile) {
Stop-Transcript
Write-Host "`n結果がファイルに保存されました: $OutputFile"
}
}
# 使用例とヘルプ
function Show-Help {
Write-Host @"
=== Multi-Format File Comparison Script ===
使用方法:
1. 2つのファイルを比較:
Compare-FilePair "C:\file1.json" "C:\file2.json"
2. 2つのフォルダを比較:
Main "C:\folder1" "C:\folder2"
3. 結果をファイルに保存:
Main "C:\folder1" "C:\folder2" "C:\diff_result.txt"
対応ファイル形式:
- JSON (.json)
- SVG/XML (.svg, .xml)
- Excel (.xlsx, .xls) ※ImportExcelモジュールが必要
- SQL (.sql)
- その他のテキストファイル
必要な準備:
Excel比較にはImportExcelモジュールをインストール:
Install-Module -Name ImportExcel -Force
"@ -ForegroundColor Cyan
}
# ヘルプ表示
Show-Help
# 実行例(コメントアウト)
# Main "C:\project\version1" "C:\project\version2" "C:\diff_results.txt"
次