如果字符 ASCII 编码大于 128,如何使用字符“_”替换文件夹中的所有文件 NAME 使用 powershell
How to replace all files NAME in A folder with character "_" if the character ASCII encoding is greater than 128 use powershell
示例文件名为
PO 2171 克雷斯科 REVISED.pdf
.....
其中很多文件,文件名不规范,space位置也不固定。
中间space是大于128的字符ASCII码,我想把大于128的字符ASCII码一次性替换成“_”
我还没学过Powershell。
非常感谢。
为此你需要正则表达式。
下面我使用 ASCII 范围 32 - 129(十六进制 \x20-\x81
)来替换任何控制字符:
(Get-ChildItem -Path 'X:\TheFolderWhereTheFilesAre' -File) |
Where-Object { $_.Name -match '[^\x20-\x81]' } |
Rename-Item -NewName { $_.Name -replace '[^\x20-\x81]+', '_' }
正则表达式详细信息:
[^\x20-\x81] Match a single character NOT in the range between ASCII character 0x20 (32 decimal) and ASCII character 0x81 (129 decimal)
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
is effective, but there's a simpler, more direct solution, using the .NET regex Unicode code block \p{IsBasicLatin}
, which directly matches any ASCII-range Unicode character (all .NET strings are Unicode strings, internally composed of UTF-16 个代码单元)。
其否定,\P{IsBasicLatin}
(注意大写P
),匹配ASCII之外的任何字符范围,以便您可以在 regex-based -replace
运算符的帮助下使用以下内容将所有 non-ASCII-range 字符替换为 _
:
(Get-ChildItem -File) | # Get all files in the current dir.
Rename-Item -NewName { $_.Name -replace '\P{IsBasicLatin', '_' } -WhatIf
注意:上面命令中的-WhatIf
common parameter预览操作。一旦您确定该操作将执行您想要的操作,请删除 -WhatIf
。
注:
在 (...)
中包含 Get-ChildItem
调用可确保在执行重命名之前 首先 收集所有匹配的文件。这可以防止 already-renamed 文件 re-entering 文件枚举可能引起的问题。
因为只有 文件 (-File
) 需要重命名,所以您不必担心 不 包含non-ASCII-range 个字符:Rename-Item
安静地忽略将文件重命名为已有名称的尝试。
- 不幸的是,对于 目录 ,这 不是 正确,这样的尝试会导致错误;这个不幸的差异在 PowerShell 7.2.4 中出现,是 GitHub issue #14903.
的主题
严格来说,.NET 字符 ([char]
(System.Char
) instances) are 16-bit Unicode code units (UTF-16), which can individually only represent a complete Unicode character in the so-called BMP (Basic Multilingual Plane),即 code-point 范围 0x0
-0xFFFF
。超出该范围的 Unicode 字符,特别是 emoji,如 ,需要用 two .NET [char]
实例,so-called 代理对表示。因此,上述解决方案替换了此类字符两个 _
个字符,如下例所示:
PS> 'A !' -replace '\P{IsBasicLatin}', '_'
A __! # !! *two* '_' chars.
示例文件名为 PO 2171 克雷斯科 REVISED.pdf ..... 其中很多文件,文件名不规范,space位置也不固定。 中间space是大于128的字符ASCII码,我想把大于128的字符ASCII码一次性替换成“_”
我还没学过Powershell。 非常感谢。
为此你需要正则表达式。
下面我使用 ASCII 范围 32 - 129(十六进制 \x20-\x81
)来替换任何控制字符:
(Get-ChildItem -Path 'X:\TheFolderWhereTheFilesAre' -File) |
Where-Object { $_.Name -match '[^\x20-\x81]' } |
Rename-Item -NewName { $_.Name -replace '[^\x20-\x81]+', '_' }
正则表达式详细信息:
[^\x20-\x81] Match a single character NOT in the range between ASCII character 0x20 (32 decimal) and ASCII character 0x81 (129 decimal)
+ Between one and unlimited times, as many times as possible, giving back as needed (greedy)
\p{IsBasicLatin}
, which directly matches any ASCII-range Unicode character (all .NET strings are Unicode strings, internally composed of UTF-16 个代码单元)。
其否定,\P{IsBasicLatin}
(注意大写P
),匹配ASCII之外的任何字符范围,以便您可以在 regex-based -replace
运算符的帮助下使用以下内容将所有 non-ASCII-range 字符替换为 _
:
(Get-ChildItem -File) | # Get all files in the current dir.
Rename-Item -NewName { $_.Name -replace '\P{IsBasicLatin', '_' } -WhatIf
注意:上面命令中的-WhatIf
common parameter预览操作。一旦您确定该操作将执行您想要的操作,请删除 -WhatIf
。
注:
在
(...)
中包含Get-ChildItem
调用可确保在执行重命名之前 首先 收集所有匹配的文件。这可以防止 already-renamed 文件 re-entering 文件枚举可能引起的问题。因为只有 文件 (
-File
) 需要重命名,所以您不必担心 不 包含non-ASCII-range 个字符:Rename-Item
安静地忽略将文件重命名为已有名称的尝试。- 不幸的是,对于 目录 ,这 不是 正确,这样的尝试会导致错误;这个不幸的差异在 PowerShell 7.2.4 中出现,是 GitHub issue #14903. 的主题
严格来说,.NET 字符 (
[char]
(System.Char
) instances) are 16-bit Unicode code units (UTF-16), which can individually only represent a complete Unicode character in the so-called BMP (Basic Multilingual Plane),即 code-point 范围0x0
-0xFFFF
。超出该范围的 Unicode 字符,特别是 emoji,如 ,需要用 two .NET[char]
实例,so-called 代理对表示。因此,上述解决方案替换了此类字符两个_
个字符,如下例所示:PS> 'A !' -replace '\P{IsBasicLatin}', '_' A __! # !! *two* '_' chars.