【问题标题】:Renaming files containing square braces重命名包含方括号的文件
【发布时间】:2019-09-04 14:29:37
【问题描述】:

用于批量重命名一个文件夹中的文件的 PS 命令确实适用于其中没有一对方括号的所有文件,但如果文件名包含一个方括号则永远不会。如果名称中有一个或多个右方括号,它也可以工作,但任何数量的左方括号都会导致错误。

错误注释:rni : Impossible de renommer l'élément situé à l'emplacement « C:\Users\X\documents\dossier\machine[3].txt », car il n'existe pas。

翻译_rni:无法重命名在«C:\Users\X\documents\dossier\machine[3].txt »中找到的元素,因为它不存在。

这是命令的代码;

$dos1=(ls C:\Users\X\documents\dos1).name
foreach ($fic in $dos1)
{rni C:\Users\X\documents\dos1\$fic §§$fic}

用户 PetSerAI 的插入“-LiteralPath”的建议适用于当前案例;

$dos1=(ls C:\Users\X\documents\dos1).name
foreach ($fic in $dos1)
{rni -literalpath C:\Users\X\documents\dos1\$fic §§$fic}

不过,对于更复杂的代码,同样的问题会再次出现; “-LiteralPath”在以下代码中没有预期的效果;

$dos1=(ls C:\Users\X\documents\dos1).name       
$dos2=(ls C:\Users\X\documents\dos2).name
foreach ($fic2 in $dos2) {foreach ($fic1 in $dos1)
{if ("$fic1" -match "$fic2") {rni -literalpath C:\Users\X\documents\dos1\$fic1 §§$fic1}}}

更糟糕的是,至少有一对不同的名称会发生​​重命名:

§§§§§§§§机器 5.txt”、“机器 5.txt”。

有没有办法在没有太多额外编码的情况下完成这项工作?

【问题讨论】:

标签: powershell square-bracket rename-item-cmdlet


【解决方案1】:
  • 正如PetSerAl 所指出的,使用-LiteralPath 参数明确地按原样传递路径,而不会将可能不需要的解释为wildcard expression,因为这就是位置由于隐式绑定到 -Path 参数,因此使用路径参数。

  • 同样,您不能使用 -match 来执行 string-literal 比较,因为 -match 的 RHS 在设计上被解释为 regex (@ 987654323@),其中[...] 也有特殊含义,就像它在通配符表达式中一样(但需要注意的是,正则表达式和通配符只是关系较远,并且通常具有根本不同的语法)。

    • 要执行字符串文字相等比较,只需使用-eq
    • 如果您需要字符串-文字子字符串匹配,请参阅this answer

因此,请使用以下内容:

$dos1=(gci -LiteralPath C:\Users\X\documents\dos1).name       
$dos2=(gci -LiteralPath C:\Users\X\documents\dos2).name
foreach ($fic2 in $dos2) {
  foreach ($fic1 in $dos1) {
   if ($fic1 -eq $fic2) { rni -LiteralPath C:\Users\X\documents\dos1\$fic1 §§$fic1 }
  }
}

注意:对于Get-ChildItem cmdlet,我已将ls 替换为更符合PowerShell 惯用的别名gci(与您对Rename-Item 使用rni 一致);但是,总的来说,最好在脚本中完全避免使用别名。

另请注意,在 PowerShell 中 - 与 Bash 等类似 POSIX 的 shell 不同 - 无需将(字符串)变量包含在 "..." 中,因为按原样引用它们可以正常工作,即使它们包含嵌入的空格;也就是说,如果$var 是一个字符串,则按原样使用它——不需要"$var"

【讨论】:

    【解决方案2】:

    这样做...

    $Files = Get-Childitem -path \\some\path

    Foreach ($Files 中的$file) {rename-item $file.FullPath -NewName (“something” + $file.Name)

    这是您想要的通用但有效的版本。问题是您实际上并没有得到对象,而是得到了一个名称列表。

    【讨论】:

    • OP 的问题与是否使用对象或路径字符串无关。通过使用参数 $file.FullPath positionally,这意味着 -Path 参数,您遇到了与 OP 相同的问题:输入路径被解释为 通配符模式 而不是作为文字路径,对于具有[ 字符的路径,它不会按预期工作。在他们里面。
    猜你喜欢
    • 2012-06-13
    • 2019-06-24
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    相关资源
    最近更新 更多