Ich konnte herausfinden, wie die GetInvalidFileNameChars()
-Methode in einem PowerShell-Skript verwendet wird. Es scheint jedoch auch Whitespace herauszufiltern (was ich NICHT will).
EDIT: Vielleicht frage ich das nicht klar genug. Ich möchte, dass die folgende Funktion die bereits in Dateinamen vorhandenen Leerzeichen einschließt. Derzeit filtert das Skript Leerzeichen heraus.
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())), '')}
Das Casting des Zeichen-Arrays in System.String
scheint die Array-Elemente tatsächlich mit Leerzeichen zu verknüpfen
[string][System.IO.Path]::GetInvalidFileNameChars()
macht das gleiche wie
[System.IO.Path]::GetInvalidFileNameChars() -join ' '
wenn du eigentlich willst
[System.IO.Path]::GetInvalidFileNameChars() -join ''
Wie in @mjolinor (+1) erwähnt, wird dies durch das Ausgabefeld-Trennzeichen ($OFS
) verursacht.
Beweis:
PS C: \> [RegEx] :: Escape ([Zeichenfolge] [IO.Path] :: GetInvalidFileNameChars ()) "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ [RegEx] :: Escape (([IO.Path] :: GetInvalidFileNameChars () -join '')) "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ [RegEx] :: Escape (([IO.Path] :: GetInvalidFileNameChars () -join '')) "\ | ☺☻ ♥ ♦\t\n♂\f\r ♫►◄↕‼ ¶§▬↨ ↑ ↓ → ← ∟ ▲ ▼:\* \?\\// PS C: \> $ OFS = '' PS C: \> [RegEx] :: Escape ([Zeichenfolge] [IO.Path] :: GetInvalidFileNameChars ()) "\ | ☺☻ ♥ ♦\t\n♂\f\r \\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Ändern Sie Ihre Funktion in etwa wie folgt:
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)
}
und es sollte tun, was Sie wollen.
Ich vermute, es hat damit zu tun, dass Zeichen, die nicht angezeigt werden, für die Regex-Operation zu [string] gezwungen werden (und am Ende als Leerzeichen ausgedrückt werden).
Sehen Sie, ob dies nicht besser funktioniert:
([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''
Dies führt zu einem direkten Zeichenvergleich und scheint zuverlässiger zu sein (eingebettete Leerzeichen werden nicht entfernt).
$name = 'abc*\ def.txt'
([char[]]$name | where { [IO.Path]::GetinvalidFileNameChars() -notcontains $_ }) -join ''
abc def.txt
Bearbeiten - Ich glaube, @Ansgar stimmt mit dem Speicherplatz überein, der durch das Umwandeln des Zeichen-Arrays in eine Zeichenfolge verursacht wird. Der Raum wird von $ OFS eingeführt.
Ich wollte Leerzeichen, um alle illegalen Zeichen zu ersetzen, damit Leerzeichen durch Leerzeichen ersetzt werden
$Filename = $ADUser.SamAccountName
[IO.Path]::GetinvalidFileNameChars() | ForEach-Object {$Filename = $Filename.Replace($_," ")}
$Filename = "folder\" + $Filename.trim() + ".txt"
Bitte probieren Sie diesen One-Liner mit der gleichen zugrunde liegenden Funktion.
passen
'?Some "" File Name <:.txt' -match ("[{0}]"-f (([System.IO.Path]::GetInvalidFileNameChars()|%{[regex]::Escape($_)}) -join '|'))
ersetzen
'?Some "" File Name <:.txt' -replace ("[{0}]"-f (([System.IO.Path]::GetInvalidFileNameChars()|%{[regex]::Escape($_)}) -join '|')),'_'
Mein aktueller Lieblingsweg, dies zu erreichen, ist:
$Path.Split([IO.Path]::GetInvalidFileNameChars()) -join '_'
Dies ersetzt alle ungültigen Zeichen durch _
und ist sehr gut lesbar.
[System.IO.Path]::GetInvalidFileNameChars()
gibt ein Array ungültiger Zeichen zurück. Wenn das Leerzeichen für Sie zurückgegeben wird (was für mich nicht der Fall ist), können Sie das Array immer wiederholen und es entfernen.
> $chars = @()
> foreach ($c in [System.IO.Path]::GetInvalidFileNameChars())
{
if ($c -ne ' ')
{
$chars += $c
}
}
Dann können Sie $chars
so verwenden, wie Sie die Ausgabe von GetInvalidFileNameChars()
verwendet hätten.