powershell - 如何使 PowerShell 处理文件名中的 [ 或 ] 好?

标签 powershell path glob literals

我从 PowerShell - Batch change files encoding To UTF-8 修改了 PowerShell 脚本.

# Modified version of https://stackoverflow.com/q/18684793

[Threading.Thread]::CurrentThread.CurrentUICulture = 'en-US'

$Encoding = New-Object System.Text.UTF8Encoding($True) # If UTF8Encoding($False), It will be UTF-8 without BOM
$source = "C:\Users\AKULA\Desktop\SRC" # source directory
$destination = "C:\Users\AKULA\Desktop\DST" # destination directory

if (!(Test-Path $destination)) {
    New-Item -Path $destination -ItemType Directory | Out-Null
}

# Delete all previously generated file
Get-ChildItem -Path $destination -Include * -File -Recurse | ForEach-Object {$_.Delete()}

# Recursively convert all files into UTF-8
foreach ($i in Get-ChildItem $source -Force -Recurse -Exclude "desktop.ini") {
    if ($i.PSIsContainer) {
        continue
    }

    $name = $i.Fullname.Replace($source, $destination)

    $content = Get-Content $i.Fullname

    if ($null -ne $content) {
        [System.IO.File]::WriteAllLines($name, $content, $Encoding)
    } else {
        Write-Host "No content from: $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 相册的链接。
完整图片列表:https://imgur.com/a/aN1RG2L

这些是我测试过的:
  • 测试文件有不同的名称。他们的名字包含空格,' ,[] .还组成了不同的语言(日语,韩语)。
  • 这些文件具有相同的内容,使用 UCS-2 BE BOM(UTF-16 BE) 编码,因此
    我可以检查它是否已重新编码为 UTF-8。

  • 如何使我的脚本句柄 []在文件名中好吗?

    最佳答案

    确实,使用 -LiteralPath参数是最好的解决方案(在 PowerShell [Core] v6+ 中,您可以缩短为 -lp ):

    $content = Get-Content -LiteralPath $i.Fullname
    
    -LiteralPath确保 $i.Fullname逐字记录(字面意思);也就是说,[]在路径中被解释为它们本身而不是具有特殊含义(见下文)。

    至于你尝试了什么 :
    $content = Get-Content $i.Fullname
    
    实际上与以下内容相同:
    $content = Get-Content -Path $i.Fullname
    
    也就是说,传递给 Get-Content 的(第一个)位置参数隐含地绑定(bind)到-Path参数 .
    -Path参数接受 wildcard expressions 允许按模式匹配路径;除了支持 * (任何字符)和? (正好 1 个字符), [...]在通配符模式中表示 字符集 或范围 (例如,[12][0-9])。
    因此,包含 [...] 的实际路径,例如,foo[10].txt , 不被识别,因为 [10]被解释为匹配单个字符的字符集,该字符是 10 ;即 foo[10].txt将匹配 foo0.txtfoo1.txt , 但不是字面上命名为 foo[10].txt 的文件.
    当(隐式)使用 -Path , 可以逃脱[]应该逐字解释的实例,即通过反引号( ` ),但请注意,当涉及引用和/或变量引用时,这可能会变得很棘手。
    如果知道路径是字面路径,最好养成使用-LiteralPath的习惯。 (在 PowerShell Core 中,您可以缩短为 -lp )。
    但是,如果您的路径包含文字 []并且还需要通配符匹配,必须使用 ` -转义 - 见 this answer .

    关于powershell - 如何使 PowerShell 处理文件名中的 [ 或 ] 好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58779892/

    相关文章:

    python glob.glob - 如何在不知道子目录中有多深的情况下查找特定文件(或文件列表)?

    java - 在 Windows 系统上构建 UNIX 路径字符串

    php - 将路径数组转换为 UL 列表

    powershell - PowerShell无法识别基本命令?术语 'get'无法识别为cmdlet的名称(错误)

    ruby - Windows Recipe 中的 Chef NOT_IF 和 ONLY_IF 验证问题

    html - 使用全局变量来包含 css

    Python、ImageMagick 和 `subprocess`

    python - 如何使用 glob.glob 模块搜索子文件夹?

    regex - 替换 ini 文件中的 block 文本

    internet-explorer - PowerShell Internet Explorer Com 对象选择类下拉菜单项