代码之家  ›  专栏  ›  技术社区  ›  wmac

将文件夹日期添加到文件夹名称

  •  2
  • wmac  · 技术社区  · 9 年前

    我有一个脚本,它递归地修改文件夹的“创建日期”和“修改日期”,以匹配文件夹中最旧和最新的文件(图像文件)。

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

    $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 回复  |  直到 9 年前
        1
  •  2
  •   Community kfsone    7 年前

    重命名文件夹可以按以下方式完成 @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"} :
      从中获取的对象 获取子项 具有布尔属性 IsContainer 指示您是否有文件夹。无需在模式上使用正则表达式匹配。此外,在PowerShell v3和更新版本中,您可以完全省略此步骤,因为 获取子项 cmdlet有一个附加参数 -Directory 只列出文件夹。

    • 误用 hungarian notation (第1部分):

      foreach ($strFolder In $colFolder) {
      

      循环变量 $strFolder 不包含字符串,但 DirectoryInfo 物体。这是一个很好的例子,说明为什么我认为匈牙利符号毫无意义地浪费了空间。

    • 避免不必要的步骤。

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

      $str文件夹 已包含 目录信息 对象以上两个语句只是将其转换为路径字符串,然后返回到 目录信息 对象简单地制作 $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
    }
    
        2
  •  1
  •   Community kfsone    7 年前

    你试过了吗

    Rename-Item oldname newname
    

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

    要做到这一点,您可以按长度顺序进行(根据定义,通往孩子的路径比父母的路径长)。这里有一个很好的例子: How do I recursively rename folders with Powershell?