2015-09-04 2 views
0

Я пытаюсь просмотреть каждый элемент в папке и добавить каждый элемент в массив, отсортированный по дате в файле в имени файла.Извлечь временную метку из имени файла и сортировки

К примеру, у меня есть три файла:

  • myfile_20150813_040949.txt
  • myfile_20150812_030949.txt
  • myfile_20150812_010949.txt

Я не уверен, как разобрать время от каждого и добавить их в массив в порядке возрастания. Любая помощь будет оценена по достоинству.

+0

Для уточнения, вы хотите добавить каждый файл в массив и отсортировать по разборной метке времени? – boeprox

+0

Есть ли что-то, что вы пробовали? Даже псевдокод лучше, чем ничего. «Myfile» когда-либо содержит символы подчеркивания? – Matt

ответ

2

Я предполагаю, что вы ищете, чтобы сортировать файлы по разборной метке времени, которая извлекается из имени файла с помощью этого примера. Это может быть не лучший подход RegEx, но он работает при тестировании.

#RegEx pattern to parse the timestamps 
$Pattern = '.*_(\d{4})(\d{2})(\d{2})_(\d{2})(\d{2})(\d{2})\.txt' 
$List = New-Object System.Collections.ArrayList 
$Temp = New-Object System.Collections.ArrayList 
Get-ChildItem | ForEach { 
    #Make sure the file matches the pattern 
    If ($_.Name -match $Pattern) { 
     Write-Verbose "Add $($_.Name)" -Verbose 
     $Date = $Matches[2],$Matches[3],$Matches[1] -join '/' 
     $Time = $Matches[4..6] -join ':' 
     [void]$Temp.Add(
      (New-Object PSObject -Property @{ 
       Date =[datetime]"$($Date) $($Time)" 
       File = $_ 
      } 
     )) 
    } 
} 
#Sort the files by the parsed timestamp and add to the main list 
$List.AddRange(@($Temp | Sort Date | Select -Expand File)) 
#Clear out the temp collection 
$Temp.Clear() 
#Display the results 
$List 
+1

Вы очищаете '$ Temp', прежде чем сортировать его. – PetSerAl

+1

Это неудобно. Спасибо за головы. – boeprox

+1

Лучше использовать '[DateTime]" $ ($ Date) $ ($ Time) "' вместо 'Get-Date '$ ($ Date) $ ($ Time)" '. Командлет Get-Date' использует текущую культуру при преобразовании из строки в 'DateTime', тогда как' [DateTime] 'cast использует инвариантную культуру. Например, для меня «Get-Date '04/09/2015'' возвращается 4 сентября 2015 года; но '[DateTime] '04/09/2015'' возвращает 9 апреля 2015 г. – PetSerAl

1

Что вы могли бы сделать для этого используется метод строки .Split() с [datetime] методом TryParseExact(). Пройдите через каждый файл и добавьте свойство для «FromFileDate», а затем выполните сортировку.

$path = "C:\temp" 
Get-ChildItem -Filter "*.txt" -Path $path | ForEach-Object{ 
    $date = ($_.BaseName).Split("_",2)[1] 
    $result = New-Object DateTime 
    if([datetime]::TryParseExact($date,"yyyyMMdd_hhmmss",[System.Globalization.CultureInfo]::InvariantCulture,[System.Globalization.DateTimeStyles]::None,[ref]$result)){ 
     # This is a good date 
     Add-Member -InputObject $_ -MemberType NoteProperty -Name "FromFileDate" -Value $result -PassThru 
    } Else { 
     # Could not parse date from filename 
     Add-Member -InputObject $_ -MemberType NoteProperty -Name "FromFileDate" -Value "Could not Parse" -PassThru 
    } 
} | Select-Object Name,fromfiledate | Sort-Object fromfiledate 

Мы берем базовое имя каждого текстового файла и разбиваем его на две части с первого подчеркивания. Используя TryParseExact, мы затем пытаемся преобразовать строку «date» в формат «yyyyMMdd_hhmmss». Поскольку мы используем TryParseExact, если у нас возникли проблемы с разбором даты, код будет продолжен.

Пример вывода

Name      FromFileDate   
----      ------------   
myfile_20150812_030949.txt 8/12/2015 3:09:49 AM 
myfile_20150813_040949.txt 8/13/2015 4:09:49 AM 
files.txt     Could not Parse  

Если вы не хотите, ошибочные данные в выходном сигнале простой Where-Object{$_.fromfiledate -is [datetime]} бы удалить эти записи.

+0

Я получаю сообщение об ошибке «Не могу найти перегрузку для« TryParseExact »и аргумент count:« 5 ». Я использую PS ver 2.0 ... это функция для версий 3.0+? –

+0

@AaronJohnsen Вам придется дважды проверить. – Matt

Смежные вопросы