【问题标题】:Rename files to lowercase in Powershell在 Powershell 中将文件重命名为小写
【发布时间】:2011-04-18 21:00:07
【问题描述】:

我正在尝试使用 Powershell 2.0 递归地重命名一堆文件。目录结构如下:

Leaflets
+ HTML
  - File1
  - File2
  ...
+ HTMLICONS
  + IMAGES
    - Image1
    - Image2
  - File1
  - File2
  ...
+ RTF
  - File1
  - File2
  ...
+ SGML
  - File1
  - File2
  ...

我正在使用以下命令:

get-childitem Leaflets -recurse | rename -newname { $_.name.ToLower() }

它似乎重命名了文件,但抱怨子目录:

Rename-Item : Source and destination path must be different.

我每月使用 robocopy 重新加载数据,但目录没有改变,所以我可以手动重命名它们。有什么方法可以让get-children 跳过子目录(如find Leaflets -type f ...)?

谢谢。

更新:看来问题出在已经全部小写的文件上。我尝试将命令更改为:

get-childitem Leaflets -recurse | if ($_.name -ne $_name.ToLower()) rename -newname { $_.name.ToLower() }

但现在 Powershell 抱怨 if 不是 cmdlet、函数等。 我可以将get-childitem 的输出通过管道传输到if 语句吗?

更新 2:可行:

$files=get-childitem Leaflets -recurse
foreach ($file in $files)
{
    if ($file.name -ne $file.name.ToLower())
    {
        rename -newname { $_.name.ToLower() }
    }
}

【问题讨论】:

  • 至少在 PowerShell 7 中,如果新名称与旧名称相同,Rename-Item 不会出错。我不确定这种行为在哪个版本中发生了变化。但是您的第一次尝试将 gci 管道连接到 rename-item 现在可以了。

标签: powershell rename recursive-descent


【解决方案1】:

即使您已经发布了自己的答案,这里有一个变体:

dir Leaflets -r | % { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } }

几点:

  • dirGet-ChildItem 的别名(-r 是 -Recurse 的缩写)。
  • %ForEach-Object 的别名。
  • -cne 是区分大小写的比较。 -ne 忽略大小写差异。
  • $_ 是您在 ForEach-Object 循环中引用当前项目的方式。
  • renRename-Item 的别名。
  • FullName 可能是首选,因为它可以确保您接触到正确的文件。

如果您想排除重命名目录,您可以包括以下内容:

if ((! $_.IsPsContainer) -and $_.Name -cne $_.Name.ToLower()) { ... }

希望这有助于继续学习和探索 PowerShell。

【讨论】:

  • 值得一提的是,这适用于重命名文件而不是目录。对于目录,您需要执行 2 次重命名操作。有关示例,请参见 here
【解决方案2】:

请记住,您可以直接通过管道连接到 Rename-Item 并使用带有 -NewName 参数的脚本块(因为它也接受管道输入)来简化此任务:

Get-ChildItem -r | Where {!$_.PSIsContainer} | 
                   Rename-Item -NewName {$_.FullName.ToLower()}

还有别名:

gci -r | ?{!$_.PSIsContainer} | rni -New {$_.FullName.ToLower()}

【讨论】:

  • 谢谢。要更改文件名,我们可以使用: gci 。 -recurse -force | ?{!$_.PSIsContainer} | rni -New {$_.Name.replace("aaa","bbb")}
【解决方案3】:

对此稍作调整,如果您只想更新特定类型文件的名称,请尝试以下操作:

get-childitem *.jpg | foreach { if ($_.Name -cne $_.Name.ToLower()) { ren $_.FullName $_.Name.ToLower() } }

这只会小写您文件夹中的 jpg 文件并忽略其余部分

【讨论】:

    【解决方案4】:

    您需要暂时将它们重命名为其他名称,然后将它们全部小写。

    $items = get-childitem -Directory -Recurse
    
    foreach ($item in $items)
    {
    
       if ($item.name -eq $item.name.ToLower())
       {    
    
           $temp = $item.FullName.ToLower() + "_"
           $name = $item.FullName.ToLower()
           ren $name $temp
    
           ren $temp $name
       }
    

    【讨论】:

      【解决方案5】:

      由于Rename-Item、管道、循环和 Windows 文件系统的工作方式的性质,前面给出的答案存在许多问题。不幸的是,我发现将给定文件夹中的所有文件和文件夹重命名为小写的最简单(此处不使用别名)解决方案是:

      Get-ChildItem -Path "/Path/To/You/Folder" -Recurse | Where{ $_.Name -cne $_.Name.ToLower() } | ForEach-Object { $tn="$($_.Name)-temp"; $tfn="$($_.FullName)-temp"; $nn=$_.Name.ToLower(); Rename-Item -Path $_.FullName -NewName $tn; Rename-Item -Path $tfn -NewName $nn -Force; Write-Host "New Name: $($nn)";}
      

      【讨论】:

        【解决方案6】:

        在 PowerShell 中,在管道中使用 where 而不是 if 更为惯用:

        gci -递归传单| ? { $_.Name -ne $_.Name.ToLower()) } | % { ren -NewName $_.Name.ToLower() }

        【讨论】:

          【解决方案7】:

          对 Jay Bazuzi 答案的一个小而重要的更正。如果 where 部分应该返回任何内容,则必须使用 -cne(区分大小写不等于)运算符。

          此外,我发现 Path 参数需要存在。这个版本在我的设置中工作:

          gci -Recurse | 
              ? { $_.Name -cne $_.Name.ToLower() } | 
              % { ren $_.Name -NewName $_.Name.Tolower()  }
          

          【讨论】:

            【解决方案8】:

            致所有关注此主题的人;以下行也可用于降低文件和目录。

            Get-ChildItem -r  | Rename-Item -NewName { $_.Name.ToLower().Insert(0,'_') } -PassThru |  Rename-Item -NewName { $_.Name.Substring(1) }
            

            主帖:https://stackoverflow.com/a/70559621/4165074

            【讨论】:

              猜你喜欢
              • 2019-04-10
              • 2011-11-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-12-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多