web-dev-qa-db-ja.com

ファイル名を保存する前に不正な文字を取り除く方法は?

PowerShellスクリプトでGetInvalidFileNameChars()メソッドを使用する方法を見つけることができました。ただし、空白も除外されているようです(これは私が望んでいないことです)。

編集:たぶん私はこれを十分に明確に尋ねていません。以下の関数に、ファイル名にすでに存在するスペースを含めたいです。現在、スクリプトはスペースを除外します。

Function Remove-InvalidFileNameChars {

param([Parameter(Mandatory=$true,
    Position=0,
    ValueFromPipeline=$true,
    ValueFromPipelineByPropertyName=$true)]
    [String]$Name
)

return [RegEx]::Replace($Name, "[{0}]" -f ([RegEx]::Escape([String][System.IO.Path]::GetInvalidFileNameChars())), '')}
20
MKANET

文字配列をSystem.Stringにキャストすると、配列要素がスペースで結合されているように見えます。つまり、

[string][System.IO.Path]::GetInvalidFileNameChars()

同じことをする

[System.IO.Path]::GetInvalidFileNameChars() -join ' '

あなたが実際に欲しいとき

[System.IO.Path]::GetInvalidFileNameChars() -join ''

@ mjolinor が言及されているように(+1)、これは 出力フィールド区切り文字$OFS)が原因です。

証拠:

PS C:\> [RegEx] :: Escape([string] [IO.Path] :: GetInvalidFileNameChars())
 "\\\ |\\☺\☻\♥\♦\♣\♠\ \\\t\\ n \♂\\f\\ r \♫\☼\►\◄\↕\ !\¶\§\▬\↨\↑\↓\→\←\∟\↔\▲\▼\:\\*\\?\ \\\ /
PS C:\> [RegEx] :: Escape(([IO.Path] :: GetInvalidFileNameChars()-join ''))
 "\\\ |\\☺\☻\♥\♦\♣\♠\ \\\t\\ n \♂\\f\\ r \♫\☼\►\◄\↕\ !\¶\§\▬\↨\↑\↓\→\←\∟\↔\▲\▼\:\\*\\?\ \\\ /
PS C:\> [RegEx] :: Escape(([IO.Path] :: GetInvalidFileNameChars()-join ''))
 "\ |☺☻♥♦\ t \n♂\ f\r♫☼►◄↕!¶§▬↨↑↓→←∟↔▲▼:\ * \?\\/
 PS C:\> $ OFS = ''
 PS C:\> [RegEx] :: Escape([string] [IO.Path] :: GetInvalidFileNameChars())
 "\ |☺☻♥♦\ t \n♂\ f\r♫☼►◄↕!¶§▬↨↑↓→←∟↔▲▼:\ * \?\\ /

関数を次のように変更します。

Function Remove-InvalidFileNameChars {
  param(
    [Parameter(Mandatory=$true,
      Position=0,
      ValueFromPipeline=$true,
      ValueFromPipelineByPropertyName=$true)]
    [String]$Name
  )

  $invalidChars = [IO.Path]::GetInvalidFileNameChars() -join ''
  $re = "[{0}]" -f [RegEx]::Escape($invalidChars)
  return ($Name -replace $re)
}

そしてそれはあなたが望むことをするはずです。

40
Ansgar Wiechers

正規表現操作で非表示文字が[string]に強制変換されている(そしてスペースとして表現されてしまう)と関係があると思います。

これがうまく機能しないかどうかを確認します。

([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''

それは単純なchar比較を行い、より信頼できるようです(埋め込まれたスペースは削除されません)。

$name = 'abc*\ def.txt'
([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''

abc def.txt

編集-@Ansgarは、文字配列を文字列にキャストすることによって引き起こされるスペースについて正しいと思います。スペースは$ OFSによって導入されています。

6
mjolinor

不正な文字をすべてスペースで置き換えてスペースをスペースに置き換えたい

$Filename = $ADUser.SamAccountName
[IO.Path]::GetinvalidFileNameChars() | ForEach-Object {$Filename = $Filename.Replace($_," ")}
$Filename = "folder\" + $Filename.trim() + ".txt"
4
John Longmuir

これを達成するための私の現在のお気に入りの方法は次のとおりです。

$Path.Split([IO.Path]::GetInvalidFileNameChars()) -join '_'

これはすべての無効な文字を_に置き換え、人間が判読できるようにします。

2
hsimah

同じ基本機能を持つこのワンライナーを試してください。

合わせる

'?Some "" File Name <:.txt' -match ("[{0}]"-f (([System.IO.Path]::GetInvalidFileNameChars()|%{[regex]::Escape($_)}) -join '|'))

交換する

'?Some "" File Name <:.txt' -replace ("[{0}]"-f (([System.IO.Path]::GetInvalidFileNameChars()|%{[regex]::Escape($_)}) -join '|')),'_'
1
user8569534

[System.IO.Path]::GetInvalidFileNameChars()は、無効な文字の配列を返します。スペース文字が返されている場合(それは私にはできません)、常に配列を反復処理して削除できます。

_> $chars = @()
> foreach ($c in [System.IO.Path]::GetInvalidFileNameChars())
  {
     if ($c -ne ' ')
     {
        $chars += $c
     }
  }
_

次に、GetInvalidFileNameChars()からの出力を使用するのと同じように、_$chars_を使用できます。

0
djs