Forked from pekeq/Fix-Combined-Character-FileName.ps1
Last active
May 6, 2024 09:10
-
-
Save 0xbadfca11/10d0bbf2c29ba456c156e7f16f5e9a3e to your computer and use it in GitHub Desktop.
Windows上で、UNICODEの結合文字が含まれるファイル名を、正規化したファイル名にリネームするスクリプト作った。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.SYNOPSIS | |
ファイル名、ディレクトリ名のUNICODE結合文字を、普通の1文字に変換する | |
.DESCRIPTION | |
ファイル名、ディレクトリ名のUNICODE結合文字になっている部分を、普通の1文字に変換する。 | |
例えば、「か + ゛(濁点記号)」を、「が」に変換する。 | |
Macは、ファイル名をUNICODE結合文字で保存するが、Windowsは、普通の1文字で保存するので、 | |
MacからWindowsに、USBメモリーでファイルをコピーした際など、MacとWindowsのファイル交換時に | |
問題が生じる。 | |
Macからファイルをコピーしてきた後で、このスクリプトを動かして、ファイル名をWindowsの | |
一般的な形式に変換しておくと、後々トラブルになりにくい。 | |
.PARAMETER Path | |
変換対象のパス名。このPath以下の全ファイル、ディレクトリに対して処理を実行する。 | |
.PARAMETER Rename | |
実際にファイル名をリネームするかどうか。 | |
.PARAMETER Confirm | |
RENコマンドを実行する前に確認するかどうか。 | |
.LINK | |
https://gist.github.com/pekeq/6182948 | |
#> | |
# このファイルはSJISで保存してください | |
Param ( | |
[String]$Path = ".", | |
[Switch]$Rename, | |
[Switch]$Confirm | |
) | |
# 文字列をUNICODE正規化する | |
# http://stackoverflow.com/questions/7836670/how-remove-accents-in-powershell/7840951#7840951 | |
function NormalizeString { | |
Param ( | |
[String]$orig = [String]::Empty | |
) | |
$norm = $orig.Normalize([System.text.NormalizationForm]::FormC) | |
$sb = New-Object Text.StringBuilder | |
$nsm = [Globalization.UnicodeCategory]::NonSpacingMark; | |
$norm.ToCharArray() | ForEach-Object { | |
if ([Globalization.CharUnicodeInfo]::GetUnicodeCategory($_) -ne $nsm) { | |
[void]$sb.Append($_) | |
} | |
} | |
$sb.ToString() | |
} | |
function NormalizeFilename { | |
Param ( | |
[Boolean]$Rename, | |
[Boolean]$Confirm | |
) | |
# http://stackoverflow.com/questions/9526455/how-can-i-control-the-order-of-processing-items-in-from-get-childitem-recurse/9526935#9526935 | |
$input | Sort-Object -Property @{ Expression = {$_.FullName.Split('\').Count} } -Desc | ForEach-Object { | |
$path = $_.FullName | |
$orig = Split-Path $path -Leaf | |
$norm = NormalizeString $orig | |
if ($orig.Length -ne $norm.Length) { | |
Write-Output $path | |
if ($Rename -eq $True) { | |
$dest = Join-Path (Split-Path $path -Parent) $norm | |
if ($Confirm -eq $True) { | |
Rename-Item -LiteralPath $path $dest -Confirm | |
} else { | |
Rename-Item -LiteralPath $path $dest | |
} | |
} | |
} | |
} | |
} | |
Get-ChildItem $Path -Recurse -Force -Directory | NormalizeFilename $Rename $Confirm | |
Get-ChildItem $Path -Recurse -Force -File | NormalizeFilename $Rename $Confirm |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment