web-dev-qa-db-fra.com

Comment supprimer les caractères illégaux avant d'essayer de sauvegarder les noms de fichiers?

J'ai pu trouver comment utiliser la méthode GetInvalidFileNameChars() dans un script PowerShell. Cependant, il semble également filtrer les espaces (ce que je ne veux pas).

EDIT: Peut-être que je ne demande pas cela assez clairement. Je veux que la fonction ci-dessous inclue les espaces qui existent déjà dans les noms de fichiers. Actuellement, le script filtre les espaces.

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())), '')}
16
MKANET

Convertir le tableau de caractères en System.String semble en fait joindre les éléments du tableau avec des espaces, ce qui signifie que

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

fait la même chose que

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

quand tu veux vraiment

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

Comme @mjolinor mentionné (+1), cela est causé par le séparateur de champ de sortie ($OFS).

Preuve:

PS C: \> [RegEx] :: Escape ([chaîne] [IO.Path] :: GetInvalidFileNameChars ())
 "\\\ |\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\¶\§\\ ↨\↑\\ →\←\∟\↔\▲\▼ \:\\ *\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 'est pas à votre place [RegEx] :: Escape (([IO.Path] :: GetInvalidFileNameChars () -join ''))
 "\\\ |\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\¶\§\\ ↨\↑\\ →\←\∟\↔\▲\▼ \:\\ *\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 'est pas à votre place [RegEx] :: Escape (([IO.Path] :: GetInvalidFileNameChars () -join ''))
 "\ | ☺☻ ♥ ♦\t\n\f\r ♫ ►◄↕ ¶§▬↨ ↑ ↓ → ← ∟↔ ▲ ▼:\* \? \\/
 PS C: \> $ OFS = ''
 PS C: \> [RegEx] :: Escape ([chaîne] [IO.Path] :: GetInvalidFileNameChars ())
 "\ | ☺☻ ♥ ♦\t\n\f\r ♫ ►◄↕ ¶§▬↨ ↑ ↓ → ← ∟↔ ▲ ▼:\* \? \\ /

Changez votre fonction pour quelque chose comme ceci:

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)
}

et il devrait faire ce que vous voulez.

33
Ansgar Wiechers

Je suppose que cela a à voir avec le fait que des caractères qui ne sont pas affichés soient forcés à utiliser [chaîne] pour l'opération de regex (et sont finalement exprimés sous forme d'espaces).

Voyez si cela ne fonctionne pas mieux:

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

Cela fera une comparaison directe des caractères, et semble être plus fiable (les espaces incorporés ne sont pas supprimés).

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

abc def.txt

Edit - Je pense que @Ansgar a raison sur l’espace créé par la conversion du tableau de caractères en chaîne. L'espace est introduit par $ OFS.

6
mjolinor

Je voulais des espaces pour remplacer tous les caractères illégaux afin que l'espace soit remplacé par de l'espace

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

S'il vous plaît essayer ce one-liner avec la même fonction sous-jacente. 

correspondre

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

remplacer

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

1
user8569534

Mon moyen actuel préféré d'y parvenir est:

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

Ceci remplace tous les caractères invalides par _ et est très lisible par l'homme.

1
hsimah

[System.IO.Path]::GetInvalidFileNameChars() renvoie un tableau de caractères non valides. S'il renvoie pour vous le caractère d'espace (ce qui n'est pas le cas pour moi), vous pouvez toujours parcourir le tableau et le supprimer.

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

Ensuite, vous pouvez utiliser $chars comme vous auriez utilisé la sortie de GetInvalidFileNameChars().

0
djs