Powershell 根据文件名中的日期戳确定最新文件
我在目录中有一系列文件,格式如下: file_ddMMyyyyhhttss.csvPowershell 根据文件名中的日期戳确定最新文件,powershell,date,Powershell,Date,我在目录中有一系列文件,格式如下: file_ddMMyyyyhhttss.csv 但不确定如何分割文件中的“日期戳”,然后按年份、月份和日期排序,以确定最新的文件。有什么建议吗?好吧,文件名中的特定格式会阻止任何有用的排序,而无需对其进行解析,但您可以这样做: Get-ChildItem $pathtofile | ForEach-Object { # isolate the timestamp $time = $_ -replace '.*(\d{12}).*','$1'
但不确定如何分割文件中的“日期戳”,然后按年份、月份和日期排序,以确定最新的文件。有什么建议吗?好吧,文件名中的特定格式会阻止任何有用的排序,而无需对其进行解析,但您可以这样做:
Get-ChildItem $pathtofile |
ForEach-Object {
# isolate the timestamp
$time = $_ -replace '.*(\d{12}).*','$1'
# parse
$timestamp = [DateTime]::ParseExact($time, 'ddMMyyyyHHmm', $null)
# add to the objects so we can sort
$_ | Add-Member -PassThru NoteProperty Timestamp $timestamp
} |
Sort-Object Timestamp
调整以适合您的确切日期/时间格式,因为您在问题中指定的格式与文件中的格式不匹配。嗯,文件名中的特定格式会阻止任何有用的排序,而无需对其进行解析,但您可以这样做:
Get-ChildItem $pathtofile |
ForEach-Object {
# isolate the timestamp
$time = $_ -replace '.*(\d{12}).*','$1'
# parse
$timestamp = [DateTime]::ParseExact($time, 'ddMMyyyyHHmm', $null)
# add to the objects so we can sort
$_ | Add-Member -PassThru NoteProperty Timestamp $timestamp
} |
Sort-Object Timestamp
调整以适合您的确切日期/时间格式,因为您在问题中指定的日期/时间格式与您的文件中指定的日期/时间格式不匹配。My proposition;)
只取文件,只取要求格式的文件,只打印日期为实际日期的文件
[System.DateTime]$parsedDate=get-date
Get-ChildItem "c:\temp\" -file -filter "*.csv" | where BaseName -match ".*(\d{12}).*" | %{
$DtString=$_.BaseName.substring($_.BaseName.Length - 12)
if ([DateTime]::TryParseExact($DtString, "ddMMyyyyhhmm",$null,[System.Globalization.DateTimeStyles]::None,[ref]$parseddate))
{
$_ | Add-Member -Name TimeInName -Value $parseddate -MemberType NoteProperty -PassThru
}
} | Sort TimeInName -Descending | Select -First 1
我的主张;)
只取文件,只取要求格式的文件,只打印日期为实际日期的文件
[System.DateTime]$parsedDate=get-date
Get-ChildItem "c:\temp\" -file -filter "*.csv" | where BaseName -match ".*(\d{12}).*" | %{
$DtString=$_.BaseName.substring($_.BaseName.Length - 12)
if ([DateTime]::TryParseExact($DtString, "ddMMyyyyhhmm",$null,[System.Globalization.DateTimeStyles]::None,[ref]$parseddate))
{
$_ | Add-Member -Name TimeInName -Value $parseddate -MemberType NoteProperty -PassThru
}
} | Sort TimeInName -Descending | Select -First 1
cmdlet不仅可以用于常规,还可以用于。这允许您对文件进行排序,而无需首先通过ForEach对象
循环。像这样:
$pattern = '.*_(\d{14}).*'
$datefmt = 'ddMMyyyyHHmmss'
$culture = [Globalization.CultureInfo]::InvariantCulture
Get-ChildItem $pathtofile | Sort-Object @{n='Timestamp';e={
$datestr = $_.Basename -replace $pattern, '$1'
[DateTime]::ParseExact($datestr, $datefmt, $culture)
}} | Select-Object -Last 1
我通常建议使用InvariantCulture
常量而不是$null
作为ParseExact()
的第三个参数,因为在某些情况下使用$null
会导致错误
如果源目录包含与文件名模式不匹配的文件,则在对其余文件进行排序之前,您可能希望使用Where Object
过滤器排除这些文件:
Get-ChildItem $pathtofile | Where-Object {
$_.Basename -match $pattern
} | Sort-Object @{n='Timestamp';e={
$datestr = $_.Basename -replace $pattern, '$1'
[DateTime]::ParseExact($datestr, $datefmt, $culture)
}} | Select-Object -Last 1
cmdlet不仅可以用于常规,还可以用于。这允许您对文件进行排序,而无需首先通过ForEach对象
循环。像这样:
$pattern = '.*_(\d{14}).*'
$datefmt = 'ddMMyyyyHHmmss'
$culture = [Globalization.CultureInfo]::InvariantCulture
Get-ChildItem $pathtofile | Sort-Object @{n='Timestamp';e={
$datestr = $_.Basename -replace $pattern, '$1'
[DateTime]::ParseExact($datestr, $datefmt, $culture)
}} | Select-Object -Last 1
我通常建议使用InvariantCulture
常量而不是$null
作为ParseExact()
的第三个参数,因为在某些情况下使用$null
会导致错误
如果源目录包含与文件名模式不匹配的文件,则在对其余文件进行排序之前,您可能希望使用Where Object
过滤器排除这些文件:
Get-ChildItem $pathtofile | Where-Object {
$_.Basename -match $pattern
} | Sort-Object @{n='Timestamp';e={
$datestr = $_.Basename -replace $pattern, '$1'
[DateTime]::ParseExact($datestr, $datefmt, $culture)
}} | Select-Object -Last 1
谢谢我引用了年、月和日期(以及我忘记的时间),因为我认为这将是决定最新版本的逻辑顺序,尽管文件名的顺序与此相反。运行脚本时,我得到:异常调用“ParseExact”并使用“3”参数:“calendar System.Globalization.GregorianCalendar中不支持由字符串表示的日期时间。“确切的格式似乎不适合您的文件名。您可以将支持的格式数组传递给
ParseExact
,以支持不同的变体。上面的代码适用于您在问题中的示例,但我不知道您的其余文件是什么样子。Sort Object
可以处理计算属性,因此您可以执行Sort Object@{n='Timestamp';e={[DateTime]::ParseExact($..Basename-replace.*..*(\d{14}.*,'1'),'ddmmyyyyyhmmss',[Globalization.CultureInfo]::InvariantCulture)}
而不首先通过每个对象的循环来传递对象。@Ansgar,的确如此。虽然我倾向于为高尔夫保留过多的内联代码,但这里的指导性帖子却没有;-)谢谢我引用了年、月和日期(以及我忘记的时间),因为我认为这将是决定最新版本的逻辑顺序,尽管文件名的顺序与此相反。运行脚本时,我得到:异常调用“ParseExact”并使用“3”参数:“calendar System.Globalization.GregorianCalendar中不支持由字符串表示的日期时间。“确切的格式似乎不适合您的文件名。您可以将支持的格式数组传递给ParseExact
,以支持不同的变体。上面的代码适用于您在问题中的示例,但我不知道您的其余文件是什么样子。Sort Object
可以处理计算属性,因此您可以执行Sort Object@{n='Timestamp';e={[DateTime]::ParseExact($..Basename-replace.*..*(\d{14}.*,'1'),'ddmmyyyyyhmmss',[Globalization.CultureInfo]::InvariantCulture)}
而不首先通过每个对象的循环来传递对象。@Ansgar,的确如此。虽然我倾向于为高尔夫保留过多的内联代码,但这里的指导性帖子却没有;-)