我有很多文件扫描的PDF文档,这些文件的名称带有包含的日期。例如:
FileA_2017-10-15.pdf
FileB_2016-04-08.pdf
FileC_2018-01-30.pdf
某些文件的格式也要在结尾加上下划线,例如...
FileD_2018-01-30_1.pdf
FileE_2018-01-30_2.pdf
甚至有一些在日期之前带有两个下划线的字符,例如...
FileF_Example_2018-01-30_1.pdf
FileG_Example_2018-01-30_2.pdf
不幸的是,它们的扫描日期与文档的实际日期不同。因此,“创建日期”和“修改日期”属性与文件名中显示的属性不同。
我希望我可以运行一个脚本来更改“创建日期”和“修改日期”以匹配文件名。
我尝试使用其他人的脚本进行此操作,但是我对PowerShell的了解不足以使其真正起作用。请注意,我不想更改文件名,而只是更改时间戳。
$Directory = "C:\TestFolder"
$DateFormat = "yyyy-MM-dd"
foreach ($file in (Get-ChildItem $Directory)) {
$date_from_file=GetFileName::[datetime])
$file.CreationTime = $date_from_file
$file.LastAccessTime = $date_from_file
$file.LastWriteTime = $date_from_file
Write-Host ($file.Name + " - " + $date_from_file)
}
如果由于我已有的东西不起作用而已经写了其他东西,则可以取消上面的代码。
编辑 想知道是否还可以将其添加到脚本中,以便它也可以将文件包含在子文件夹中。如果该文件夹上的“修改日期”为今天,则可能仅以该文件夹中文件的方式编写脚本。我想在一个可能具有许多子文件夹的父文件夹上运行此文件,如果这些文件夹没有今天的“修改日期”,那么它应该跳过该文件夹中的文件。我当时在想可以加快这个过程。敞开心thought,感谢您的帮助!
答案 0 :(得分:1)
您距离很近,您需要
$
## Q:\Test\2019\05\19\SO_56211626.ps1
$Directory = "C:\TestFolder"
foreach ($file in (Get-ChildItem -Path $Directory -Filter *.pdf)){
if($File.BaseName -match '_(\d{4}-\d{2}-\d{2})(_\d)?$'){
$date_from_file= (Get-Date $Matches[1])
$file.CreationTime = $date_from_file
$file.LastAccessTime = $date_from_file
$file.LastWriteTime = $date_from_file
$file | Select-Object Name,CreationTime,LastAccessTime,LastWriteTime
}
}
示例输出:
> Q:\Test\2019\05\19\SO_56211626.ps1
Name CreationTime LastAccessTime LastWriteTime
---- ------------ -------------- -------------
FileA_2017-10-15.pdf 2017-10-15 00:00:00 2017-10-15 00:00:00 2017-10-15 00:00:00
FileB_2016-04-08.pdf 2016-04-08 00:00:00 2016-04-08 00:00:00 2016-04-08 00:00:00
FileC_2018-01-30.pdf 2018-01-30 00:00:00 2018-01-30 00:00:00 2018-01-30 00:00:00
英语语言环境(美国)产生:
Name CreationTime LastAccessTime LastWriteTime
---- ------------ -------------- -------------
FileA_2017-10-15.pdf 10/15/2017 12:00:00 AM 10/15/2017 12:00:00 AM 10/15/2017 12:00:00 AM
FileB_2016-04-08.pdf 4/8/2016 12:00:00 AM 4/8/2016 12:00:00 AM 4/8/2016 12:00:00 AM
FileC_2018-01-30.pdf 1/30/2018 12:00:00 AM 1/30/2018 12:00:00 AM 1/30/2018 12:00:00 AM
答案 1 :(得分:1)
[
编辑-由于OP在我建议的修复程序中遇到了非常奇怪的错误-我无法使用示例数据重现的错误-我已将此答案更改为完整的建议代码。
编辑2-添加了新的文件名变体和代码来处理它们。
编辑3-由于示例数据再次更改,因此从拆分更改为正则表达式匹配。 [*叹息... *]
]
您实际上并不是在创建所需的datetime对象。 $date_from_file=
行除了创建红色错误消息... [咧嘴]
替换此行...
$date_from_file=GetFileName::[datetime])
...此行...
$date_from_file = [datetime]::ParseExact($File.BaseName.Split('_')[-1], $DateFormat, $Null)
...,并且您的$date_from_file
变量将包含一个正确的[datetime]
对象,该对象将在您的分配中起作用。
i可能会更改这些分配的顺序,以将$file.LastAccessTime = $date_from_file
置于最后,这样,下一行就不会更改它。
,该值将在每次访问文件时更改,因此可能不值得更改。 [咧嘴]
这是完整的脚本以及它的功能-
它做什么...
.BaseName
转换为[datetime]
对象.CreationTime
,.LastWriteTime
和.LastAccessTime
的值从文件名分配给日期时间这是代码...
$Directory = $env:TEMP
$DateFormat = "yyyy-MM-dd"
# create some test files
$TestFileList = @(
'FileA_2017-10-15.pdf'
'FileB_2016-04-08.pdf'
'FileC_2018-01-30.pdf'
'FileD_2019-09-09_1.pdf'
'FileE_2015-05-05_2.pdf'
)
foreach ($TFL_Item in $TestFileList)
{
$Null = New-Item -Path $Directory -Name $TFL_Item -ItemType File -Force
}
$FileList = Get-ChildItem -LiteralPath $Directory -Filter '*.pdf' -File
foreach ($FL_Item in $FileList) {
# removed split, added regex match to work with ever-growing list of variant file names
$Null = $FL_Item.BaseName -match '_(?<DateString>\d{4}-\d{2}-\d{2})'
$DateString = $Matches.DateString
$date_from_file = [datetime]::ParseExact($DateString, $DateFormat, $Null)
$FL_Item.CreationTime = $date_from_file
$FL_Item.LastWriteTime = $date_from_file
$FL_Item.LastAccessTime = $date_from_file
# show the resulting datetime info
'=' * 20
$CurrentFileInfo = Get-Item -LiteralPath $FL_Item.FullName
$CurrentFileInfo.FullName
$CurrentFileInfo.CreationTime
$CurrentFileInfo.LastWriteTime
$CurrentFileInfo.LastAccessTime
}
屏幕输出...
====================
C:\Temp\FileA_2017-10-15.pdf
2017 October 15, Sunday 12:00:00 AM
2017 October 15, Sunday 12:00:00 AM
2017 October 15, Sunday 12:00:00 AM
====================
C:\Temp\FileB_2016-04-08.pdf
2016 April 08, Friday 12:00:00 AM
2016 April 08, Friday 12:00:00 AM
2016 April 08, Friday 12:00:00 AM
====================
C:\Temp\FileC_2018-01-30.pdf
2018 January 30, Tuesday 12:00:00 AM
2018 January 30, Tuesday 12:00:00 AM
2018 January 30, Tuesday 12:00:00 AM
====================
C:\Temp\FileD_2019-09-09_1.pdf
2019 September 09, Monday 12:00:00 AM
2019 September 09, Monday 12:00:00 AM
2019 September 09, Monday 12:00:00 AM
====================
C:\Temp\FileE_2015-05-05_2.pdf
2015 May 05, Tuesday 12:00:00 AM
2015 May 05, Tuesday 12:00:00 AM
2015 May 05, Tuesday 12:00:00 AM
我直接在资源管理器中检查了文件,并且它们与显示的值匹配。
答案 2 :(得分:0)
谢谢。我被困在没有这个线程的情况下。我最终得到了一个变体,该变体将任何文件名与正确格式的日期匹配,因此:
# Call like:
# powershell -NoLogo -ExecutionPolicy Unrestricted -Sta -NonInteractive -WindowStyle Normal -File ".\Rename_files_selected_folders_ModifyDateStamps.ps1" -Folder "T:\files"
# 1. capture a commandline parameter 1 as a mandatory "Folder string" with a default value
param ( [Parameter(Mandatory=$true)] [string]$Folder = "T:\HDTV\autoTVS-mpg\Converted" )
[console]::BufferWidth = 512
$DateFormat = "yyyy-MM-dd"
write-output "Processing Folder: ",$Folder
# 2. Iterate the files
$FileList = Get-ChildItem -Recurse $Folder -Include '*.mp4','*.bprj','*.ts' -File
foreach ($FL_Item in $FileList) {
$ixxx = $FL_Item.BaseName -match '(?<DateString>\d{4}-\d{2}-\d{2})'
if($ixxx){
#write-output $FL_Item.FullName
$DateString = $Matches.DateString
$date_from_file = [datetime]::ParseExact($DateString, $DateFormat, $Null)
$FL_Item.CreationTime = $date_from_file
$FL_Item.LastWriteTime = $date_from_file
$FL_Item | Select-Object FullName,CreationTime,LastWriteTime
}
}
# https://stackoverflow.com/questions/56211626/powershell-change-file-date-created-and-date-modified-based-on-filename