Windowsファイルシステム(ネットワークのOS Xクライアントによってそこに置かれた)上の不正なファイル名をクリーンアップする関数を作成/変更しようとしています。スクリプトは正常に動作しますが、正規表現で特定のメタ文字を渡そうとすると、-AllMatches で実行されるチェックは、肯定的な一致に対して false を返します (テストのために意図的に違法な名前のフォルダーを使用します)。文字が (提供されたループを使用せずに) 個別に処理された場合、それらは true を返します。私はすべてのエスケープ方法 (および \ と ` の 2 つの組み合わせ) を試しましたが、うまくいきませんでした。その他の特殊文字 (& など) は正常に機能します。
なぜこのように動作するのか、誰にも考えがありますか? (注: 以下でコメント化されている不正な文字の 2 つの宣言は、機能しない文字と機能する文字に分けられます。
function Check-IllegalCharacters ($Path, [switch]$Fix, [switch]$Verbose)
{
Write-Host Checking files in $Path, please wait...
#Get all files and folders under the path specified
$items = Get-ChildItem -Path $Path -Recurse
foreach ($item in $items)
{
#Check if the item is a file or a folder
if ($item.PSIsContainer) { $type = "Folder" }
else { $type = "File" }
#Report item has been found if verbose mode is selected
if ($Verbose) { Write-Host Found a $type called $item.FullName }
#Check if item name is 128 characters or more in length
if ($item.Name.Length -gt 127)
{
Write-Host $type $item.Name is 128 characters or over and will need to be truncated -ForegroundColor Red
}
else
{
#$illegalChars = '[<>?*|/\:"]' $illegalChars = '[&{}~#%]'
#Got this from http://powershell.com/cs/blogs/tips/archive/2011/05/20/finding-multiple-regex-matches.aspx
$illegalChars = '[&{}~#%]'
filter Matches($illegalChars)
{
$item.Name | Select-String -AllMatches $illegalChars |
Select-Object -ExpandProperty Matches
Select-Object -ExpandProperty Values
}
#Replace illegal characters with legal characters where found
$newFileName = $item.Name
Matches $illegalChars | ForEach-Object {
Write-Host $type $item.FullName has the illegal character $_.Value -ForegroundColor Red
#These characters may be used on the file system but not SharePoint
if ($_.Value -match "&") { $newFileName = ($newFileName -replace "&", "and") }
if ($_.Value -match "{") { $newFileName = ($newFileName -replace "{", "(") }
if ($_.Value -match "}") { $newFileName = ($newFileName -replace "}", ")") }
if ($_.Value -match "~") { $newFileName = ($newFileName -replace "~", "-") }
if ($_.Value -match "#") { $newFileName = ($newFileName -replace "#", "") }
if ($_.Value -match "%") { $newFileName = ($newFileName -replace "%", "") }
}
#Check for start, end and double periods
if ($newFileName.StartsWith(".")) { Write-Host $type $item.FullName starts with a period -ForegroundColor red }
while ($newFileName.StartsWith(".")) { $newFileName = $newFileName.TrimStart(".") }
if ($newFileName.EndsWith(".")) { Write-Host $type $item.FullName ends with a period -ForegroundColor Red }
while ($newFileName.EndsWith(".")) { $newFileName = $newFileName.TrimEnd(".") }
if ($newFileName.Contains("..")) { Write-Host $type $item.FullName contains double periods -ForegroundColor red }
while ($newFileName.Contains("..")) { $newFileName = $newFileName.Replace("..", ".") }
#Fix file and folder names if found and the Fix switch is specified
if (($newFileName -ne $item.Name) -and ($Fix))
{
Rename-Item $item.FullName -NewName ($newFileName)
Write-Host $type $item.Name has been changed to $newFileName -ForegroundColor Blue
}
}
}
}
誰かが助けてくれたらどうもありがとう!
編集:さらに明確にするために、ここの関数はそのままで正常に機能します。それは、正規表現を他のバリアント $illegalChars = '[<>?*|/\:"]' に変更する (および必要に応じてエスケープする) 場合のみです。正常に動作し、エラーは発生しませんが、これらの文字が含まれるファイルやフォルダーは検出されません。
関数をロードしてから、'Check-IllegalCharacters -Path $path -Verbose' を実行して実行できます。