将文件夹日期添加到foldername

时间:2015-12-29 19:48:35

标签: powershell file-rename

我有一个脚本,以递归方式修改"创建日期"和#34;修改日期"文件夹以匹配文件夹(图像文件)中最旧和最新的文件。

之后我想将每个文件夹的创建日期添加为其名称的前缀。我编写了创建所需名称的代码,但我不知道如何重命名文件夹。

$colFolder = Get-ChildItem -Recurse "." |
             Where-Object {$_.mode -match "d"} |
             Sort-Object Fullname -Descending
$VerbosePreference = "Continue"
foreach ($strFolder In $colFolder) {
  Trap [Exception] {
    Write-Verbose "TRAPPED:" 
    Write-Verbose $_.Exception.Message;
    Write-Verbose $strFolder.FullName
    Continue
  }
  $Path = $strFolder.FullName
  $Folder = Get-Item $Path

  # Get Newest file in folder
  $strOldestTime = (Get-ChildItem $Path | Sort-Object LastWriteTime | Select-Object -First 1).LastWriteTime
  $strNewestTime = (Get-ChildItem $Path | Sort-Object LastWriteTime | Select-Object -Last  1).LastWriteTime

  # Change the date to match the newest file if it doesn't already
  $Folder.CreationTime = $strOldestTime
  $Folder.LastWriteTime = $strNewestTime

  # add the date as the prefix of the folder (in which the files are)
  $date = $strOldestTime.ToString('yyyy-MM-dd')
  $foldername = $Folder.Name.split("\")[-1]
  Write-Verbose "$date- $foldername"

  #now rename the folder to above name
}

2 个答案:

答案 0 :(得分:2)

重命名文件夹可以@onupdatecascade中描述的his answer完成。

Rename-Item -Path $Folder.FullName -NewName $newname

如果您至少拥有PowerShell v3(我强烈推荐),您可以使用参数-LiteralPath作为当前文件夹路径,以避免出现特殊字符问题:

Rename-Item -LiteralPath $Folder.FullName -NewName $newname

话虽如此,我想建议您对代码进行一些改进。

  • Get-ChildItem -Recurse "."
    Get-ChildItem默认使用当前工作目录,因此可以省略"."

  • Where-Object {$_.mode -match "d"}
    Get-ChildItem获得的对象具有布尔属性IsContainer,指示您是否有文件夹。无需在模式上使用正则表达式匹配。此外,在PowerShell v3及更高版本中,您可以完全省略此步骤,因为Get-ChildItem cmdlet具有仅列出文件夹的附加参数-Directory

  • 误用hungarian notation(第1页):

    foreach ($strFolder In $colFolder) {
    

    循环变量$strFolder不包含字符串,而是DirectoryInfo个对象。这是为什么我认为匈牙利符号无意义地浪费空间的一个主要例子。

  • 避免不必要的步骤。

    $Path = $strFolder.FullName
    $Folder = Get-Item $Path
    

    $strFolder已包含DirectoryInfo个对象。以上两个语句只是将其转换为路径字符串并返回到DirectoryInfo对象。只需将$Folder设为循环变量(见上文)。

  • 避免重复代码(特别是重复的磁盘操作):

    $strOldestTime = (Get-ChildItem $Path | Sort-Object LastWriteTime | Select-Object -First 1).LastWriteTime
    $strNewestTime = (Get-ChildItem $Path | Sort-Object LastWriteTime | Select-Object -Last  1).LastWriteTime
    

    不是多次列出和排序子项,而是只运行一次语句并将结果收集到变量中:

    $items = Get-ChildItem $Path | Sort-Object LastWriteTime
    $strOldestTime = ($items | Select-Object -First 1).LastWriteTime
    $strNewestTime = ($items | Select-Object -Last 1).LastWriteTime
    

    另外,我只是展开LastWriteTime属性,而不是在子表达式中运行Select-Object

    $strOldestTime = $items | Select-Object -First 1 -Expand LastWriteTime
    $strNewestTime = $items | Select-Object -Last 1 -Expand LastWriteTime
    
  • 误用匈牙利符号(第2页):
    $strOldestTime$strNewestTime包含DateTime个对象,而非字符串。

  • $foldername = $Folder.Name.split("\")[-1]
    Name属性已包含没有路径的文件夹名称,因此无需拆分。

  • 使用format operator从日期和当前名称构建新文件夹名称:

    $newname = '{0:yyyy-MM-dd} - {1}' -f $oldestTime, $Folder.Name
    
  • 如果您有可能多次运行该脚本,则可能需要从文件夹名称中删除现有的前导日期,以便日期不会“堆叠”:

    $Folder.Name -replace '^\d{4}-\d{2}-\d{2} - '
    

简化代码:

$colFolder = Get-ChildItem -Recurse |
             Where-Object { $_.PSIsContainer } |
             Sort-Object Fullname -Descending

foreach ($folder in $colFolder) {
  $items = Get-ChildItem $folder.FullName | Sort-Object LastWriteTime

  $folder.CreationTime  = $items | Select-Object -First 1 -Expand LastWriteTime
  $folder.LastWriteTime = $items | Select-Object -Last 1 -Expand LastWriteTime

  $newname = '{0:yyyy-MM-dd} - {1}' -f $folder.CreationTime, ($folder.Name -replace '^\d{4}-\d{2}-\d{2} - ')

  Rename-Item -Path $folder.FullName -NewName $newname
}

或(PowerShell v3及更新版):

$colFolder = Get-ChildItem -Recurse -Directory |
             Sort-Object Fullname -Descending

foreach ($folder in $colFolder) {
  $items = Get-ChildItem $folder.FullName | Sort-Object LastWriteTime

  $folder.CreationTime  = $items | Select-Object -First 1 -Expand LastWriteTime
  $folder.LastWriteTime = $items | Select-Object -Last 1 -Expand LastWriteTime

  $newname = '{0:yyyy-MM-dd} - {1}' -f $folder.CreationTime, ($folder.Name -replace '^\d{4}-\d{2}-\d{2} - ')

  Rename-Item -LiteralPath $folder.FullName -NewName $newname
}

答案 1 :(得分:1)

你试过吗

Rename-Item oldname newname

它适用于简单的示例,但可能会破坏嵌套在其他文件夹中的文件夹和递归,因为您可以在脚本完成之前重命名文件夹。

要管理您可以按长度顺序执行它们(根据定义,子项的路径长于父项的路径)。这里的好例子是:How do I recursively rename folders with Powershell?