如何使PowerShell处理文件名中的[或]? [英] How can I make PowerShell handle [ or ] in file name well?

查看:91
本文介绍了如何使PowerShell处理文件名中的[或]?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从 PowerShell修改了PowerShell脚本-批量更改编码为UTF-8的文件.

# 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无法很好地处理[]. 我制作了一些名称/内容具有多样性的测试文件.

But after using it, I've found that PS cannot handle [ or ] well. I made some test files that has diversity in name/content.

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

Since I cannot embed images in question, here is link of IMGUR album.
Full image list: https://imgur.com/a/aN1RG2L

这些是我测试过的:

  • 测试文件具有不同的名称.他们的名字包含空格,'[].还组成了不同的语言(日语,韩语).
  • 这些文件具有相同的内容,并使用UCS-2 BE BOM(UTF-16 BE)进行编码,因此 我可以检查它是否已重新编码为UTF-8.
  • Test files have different names. Their name contains space, ', []. Also made up different language(Japanese, Korean).
  • These files have same content, encoded with UCS-2 BE BOM(UTF-16 BE) so that I can check if it has re-encoded to UTF-8.

如何使脚本的文件名正确地处理[]?

How can I make my script handle [ or ] in file name well?

推荐答案

实际上,最好使用-LiteralPath参数:

Indeed, use of the -LiteralPath parameter is the best solution:

$content = Get-Content -LiteralPath $i.Fullname

-LiteralPath确保$i.Fullname被采用 verbatim (字面意思);也就是说,路径中的[]被解释为它们自己,而不具有特殊含义(见下文).

-LiteralPath ensures that $i.Fullname is taken verbatim (literally); that is, [ and ] in the path are interpreted as themselves rather than having special meaning (see below).

关于您尝试过的事情:

$content = Get-Content $i.Fullname

实际上与以下内容相同:

is effectively the same as:

$content = Get-Content -Path $i.Fullname

也就是说,传递给Get-Content的(第一个) positional 参数隐式绑定到-Path参数.

That is, the (first) positional argument passed to Get-Content is implicitly bound to the -Path parameter.

-Path参数接受

The -Path parameter accepts wildcard expressions to allow matching paths by patterns; in addition to support for * (any run of characters) and ? (exactly 1 character), [...] inside a wildcard pattern denotes a character set or range (e.g., [12] or [0-9]).

因此,包含[...](例如foo[10].txt)的实际路径不会被识别,因为[10]被解释为与 single 10的字符;是foo[10].txt会匹配foo0.txtfoo1.txt,但不能匹配字面名为foo[10].txt的文件.

Therefore an actual path that contains [...], e.g., foo[10].txt, is not recognized as such, because the [10] is interpreted as a character set matching a single character that is either 1 or 0; that is foo[10].txt would match foo0.txt and foo1.txt, but not a file literally named foo[10].txt.

(隐式)使用-Path时, 可以转义 []实例,这些实例应逐字解释,即通过反引号( `),但请注意,在涉及引用和/或变量引用时,这样做可能会很棘手.

When (implicitly) using -Path, it is possible to escape [ and ] instances that should be interpreted verbatim, namely via the backtick (`), but note that this can get tricky to get right when quoting and/or variable references are involved.

如果您知道路径是文字路径,则最好养成使用-LiteralPath 的习惯(在PowerShell Core 中可以将其缩短为-lp).

If you know a path to be a literal path, it is best to form a habit of using -LiteralPath (which in PowerShell Core you can shorten to -lp).

但是,如果路径包含 literal []并且 还需要通配符匹配,则必须使用` -escapeing -请参见此答案.

However, if your path contains literal [ and ] and you also need wildcard matching, you must use `-escaping - see this answer.

这篇关于如何使PowerShell处理文件名中的[或]?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆