我有一个脚本,以递归方式修改"创建日期"和#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
}
答案 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?