Powershell 根据文件名中的日期戳确定最新文件

Powershell 根据文件名中的日期戳确定最新文件,powershell,date,Powershell,Date,我在目录中有一系列文件,格式如下: file_ddMMyyyyhhttss.csv 但不确定如何分割文件中的“日期戳”,然后按年份、月份和日期排序,以确定最新的文件。有什么建议吗?好吧,文件名中的特定格式会阻止任何有用的排序,而无需对其进行解析,但您可以这样做: Get-ChildItem $pathtofile | ForEach-Object { # isolate the timestamp $time = $_ -replace '.*(\d{12}).*','$1'

我在目录中有一系列文件,格式如下:

file_ddMMyyyyhhttss.csv
但不确定如何分割文件中的“日期戳”,然后按年份、月份和日期排序,以确定最新的文件。有什么建议吗?

好吧,文件名中的特定格式会阻止任何有用的排序,而无需对其进行解析,但您可以这样做:

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,的确如此。虽然我倾向于为高尔夫保留过多的内联代码,但这里的指导性帖子却没有;-)