如何使PowerShell能够很好地处理文件名中的[或]?
我从中修改了PowerShell脚本如何使PowerShell能够很好地处理文件名中的[或]?,powershell,path,glob,literals,Powershell,Path,Glob,Literals,我从中修改了PowerShell脚本 #的修改版本https://stackoverflow.com/q/18684793 [Threading.Thread]::CurrentThread.CurrentUICulture='en US' $Encoding=New Object System.Text.UTF8Encoding($True)#如果UTF8Encoding($False),它将是不带BOM的UTF-8 $source=“C:\Users\AKULA\Desktop\SRC”#源
#的修改版本https://stackoverflow.com/q/18684793
[Threading.Thread]::CurrentThread.CurrentUICulture='en US'
$Encoding=New Object System.Text.UTF8Encoding($True)#如果UTF8Encoding($False),它将是不带BOM的UTF-8
$source=“C:\Users\AKULA\Desktop\SRC”#源目录
$destination=“C:\Users\AKULA\Desktop\DST”#目标目录
如果(!(测试路径$destination)){
新项目-路径$destination-项目类型目录| Out Null
}
#删除以前生成的所有文件
Get-ChildItem-Path$destination-Include*-File-Recurse | ForEach对象{$\.Delete()}
#递归地将所有文件转换为UTF-8
foreach($i in Get ChildItem$source-Force-Recurse-Exclude“desktop.ini”){
如果($i.PSIsContainer){
持续
}
$name=$i.Fullname.Replace($source,$destination)
$content=获取内容$i.Fullname
如果($null-ne$content){
[System.IO.File]::writeAllines($name、$content、$Encoding)
}否则{
编写主机“没有来自:$i的内容”
}
}
但是在使用它之后,我发现PS不能很好地处理[
或]
。
我制作了一些名称/内容多样的测试文件
Get-Content : An object at the specified path C:\Users\AKULA\Desktop\SRC\FILENAME[[[[[[]]]]]]]].txt does not exist, or
has been filtered by the -Include or -Exclude parameter.
At C:\Users\AKULA\Desktop\Convert_to_UTF-8.ps1:24 char:16
+ $content = Get-Content $i.Fullname
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (System.String[]:String[]) [Get-Content], Exception
+ FullyQualifiedErrorId : ItemNotFound,Microsoft.PowerShell.Commands.GetContentCommand
由于我无法嵌入有问题的图像,这里是IMGUR相册的链接。完整图像列表: 这些是我测试过的:
- 测试文件有不同的名称。它们的名称包含空格,
,”
。也组成了不同的语言(日语、韩语)[]
- 这些文件具有相同的内容,使用UCS-2 BE BOM(UTF-16 BE)编码,因此 我可以检查它是否重新编码为UTF-8
如何使脚本能够很好地处理文件名中的
[
或]
?事实上,使用-LiteralPath
参数是最好的解决方案(在PowerShell[Core]v6+中,可以缩短为-lp
):
-LiteralPath
确保$i.Fullname
是逐字(字面)获取的;也就是说,路径中的[
和]
被解释为它们自己,而不是具有特殊意义(见下文)
至于你所尝试的:
$content = Get-Content $i.Fullname
实际上与以下内容相同:
$content = Get-Content -Path $i.Fullname
也就是说,传递给Get Content
的(第一个)位置参数隐式绑定到-路径
参数
-Path
参数接受以允许按模式匹配路径;除了支持*
(任何字符运行)和?
(正好1个字符),[…]
内的通配符模式表示字符集或范围(例如,[12]
或[0-9]
)
因此,包含[…]
的实际路径(例如foo[10].txt
)无法识别为该路径,因为[10]
被解释为与单个字符匹配的字符集,该字符集是1
或0
;这就是foo[10].txt
将匹配foo0.txt
和foo1.txt
,但不是字面上命名为foo[10].txt的文件
当(隐式地)使用-Path
时,可以转义应该逐字解释的[
和]
实例,即通过反勾(`
),但请注意,当涉及引用和/或变量引用时,这可能会变得很难正确
如果您知道路径是文本路径,最好养成使用-LiteralPath
的习惯(在PowerShell Core中,您可以将其缩短为-lp
)
但是,如果路径包含literal[
和]
并且还需要通配符匹配,则必须使用`
-escaping-请参见。-LiteralPath
与-path
PowerShell处理方括号[]
类似于正则表达式中的字符类。@PetSerAl您的意思是$content=Get content-LiteralPath$i.Fullname
?
$content = Get-Content -Path $i.Fullname