在Powershell中将文件重命名为小写

时间:2010-09-29 14:44:47

标签: powershell rename recursive-descent

我正在尝试使用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() }
    }
}

7 个答案:

答案 0 :(得分:23)

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

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

有些观点:

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

如果要排除重命名目录,可以包含以下内容:

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

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

答案 1 :(得分:12)

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

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

和别名:

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

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

$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
   }

答案 4 :(得分:1)

由于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)";}

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

对杰伊·巴祖兹(Jay Bazuzi)的回答进行了微小但重要的更正。如果where部分应该返回任何内容,则必须使用-cne(区分大小写的不相等)运算符。

此外,我发现需要提供Path参数。此版本适用于我的设置:

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