Извлекать даты из имен файлов, затем обрабатывать файлы по дате в порядке возрастания - Powershell - PullRequest
2 голосов
/ 22 января 2020

Сначала я предоставлю свой код, а затем объясню.

$toImport = gci "\\server\folder\*" -include "Examplefile*.txt"
$toImport = $toImport.fullname

$date_of_file = @()

foreach($item in $toImport){
    $date_of_file += (split-path $item -leaf).substring(11,6) 

}

write-host ($date_of_file | sort-object)

Я получаю имена файлов с помощью get-childitem, а затем просто помещаю их полный путь в массив. Моя переменная $toImport содержит пути к файлам и выглядит следующим образом:

\\server\folder\Examplefile010220.txt
\\server\folder\Examplefile010320.txt
\\server\folder\Examplefile010420.txt
\\server\folder\Examplefile010520.txt
\\server\folder\Examplefile120919.txt

Затем я использую split-path, чтобы получить только имя файла, где я могу запустить .substring(), чтобы извлечь даты, а затем Я добавляю эти даты в переменную $date_of_file, которая в приведенном выше примере будет содержать эти значения ... 010220 010320 010420 010520 120919

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

Некоторые вещи, которые я пытался исправить вышеприведенным скриптом: (get-date -date $ date_of_file | sort-object)

($date_of_file.ToString('MMddyy') | sort-object)

$date_of_file += ((split-path $item -leaf).substring(11,6) ).toString("MMddyy")

$date_of_file += get-date -date ((split-path $item -leaf).substring(11,6) )

($date_of_file | Sort-Object { $_. -as [datetime] })

$date_of_file += [datetime]::parseexact(((split-path $item -leaf).substring(11,6) ), 'MMddyy', $null).ToString('MMddyy')

Как получить сортировку по дате в порядке возрастания? До сих пор каждый раз, когда я что-то пробую, я сталкиваюсь с ошибками, или эта дата все еще находится в конце списка, «120919», когда она должна быть первой.

================= ОБНОВЛЕНИЕ

$toImport = gci "\\server\folder\*" -include "Examplefile*.txt"
$toImport = $toImport.fullname
cls

$date_of_file = @()

foreach($item in $toImport){
    $date_of_file += [datetime]::parseexact(((split-path $item -leaf).substring(11,6) ), 'MMddyy', $null)

}

write-host ($date_of_file | Sort-Object)

Этот бит, кажется, работает, но он ставит формат даты в формате, который выглядит как Thursday, January 2, 2020 12:00:00 AM. и я попытался сделать .ToString ('MMddyy') на результат, но я получаю эту ошибку Cannot find an overload for "ToString" and the argument count: "1".

Ответы [ 4 ]

4 голосов
/ 22 января 2020

Краткое и эффективное решение, которое напрямую сортирует экземпляры System.IO.FileInfo, выводимые по Get-ChildItem в хронологическом порядке, подразумеваемом форматированными MMddyy строками даты, встроенными в имена файлов:

Get-ChildItem \\server\folder -Filter Examplefile*.txt |
  Sort-Object { $_.BaseName -replace '.+(\d{2})(\d{2})(\d{2})', '$3$1$2' }
  • Get-ChildItem \\server\folder -Filter Examplefile*.txt:

    • -Filter - это наиболее эффективный способ поиска файлов, соответствующих заданному шаблону подстановочного знака, поскольку он фильтрует источник ( файловой системы) вместо того, чтобы сначала извлекать все элементы, а затем делать фильтр PowerShell по факту (что и происходит с -Include).
  • Sort-Object { $_.BaseName -replace '.+(\d{2})(\d{2})(\d{2})', '$3$1$2' }:

    • Передача блока сценария ({ ... }) параметру Sort-Object (подразумевается) -Property приводит к тому, что блок сценария оценивается для каждого входного объекта, а входной объект под рукой отражается в automati c переменная $_.

    • Операция -replace использует подстановку строк на основе регулярных выражений, которая эффективно переставляет встроенную строку даты из MMddyy в yyMMdd формате и сортирует на основе последний, так что лексическая сортировка равна хронологическая сортировка.

1 голос
/ 22 января 2020

Я думаю, у вас может быть проблема в том, что вы ВИДЕТЕ. ваш отсортированный список должен иметь файл 120919 в КОНЕЦ "новейшего первого" списка, поскольку остальные все в 2020 году, а не в 2019.

однако, вот моя версия решение проблемы. «волхвы c» в этом случае получают только цифры из конца .BaseName файла. с тех пор как вы выбросили это, мне пришлось использовать разделение и регулярное выражение. [ ухмылка ]

$FileNameList = @(
    '\\server\folder\Examplefile010220.txt'
    '\\server\folder\Examplefile010320.txt'
    '\\server\folder\Examplefile010420.txt'
    '\\server\folder\Examplefile010520.txt'
    '\\server\folder\Examplefile120919.txt'
    )

$FileNameList |
    # this would be far easier if you have left things as fileinfo objects [*grin*] 
    Sort-Object -Descending -Property {
        [datetime]::ParseExact(($_.Split('.')[0] -replace '.+(\d{6})', '$1'), 'MMddyy', $Null)
        }

output ...

\\server\folder\Examplefile010520.txt
\\server\folder\Examplefile010420.txt
\\server\folder\Examplefile010320.txt
\\server\folder\Examplefile010220.txt
\\server\folder\Examplefile120919.txt

обратите внимание, что последний файл - с 2019 года, а остальные - с 2020 года. [ ухмылка ]

1 голос
/ 22 января 2020

Это может сработать для вас. Он добавляет SortableName свойство yyddMM, затем сортирует по этому свойству:

dir "\\server\folder\*" -include "Examplefile*.txt" | `
  Select-Object -Property *, @{ Name = 'SortableName'; Expression = {$_.BaseName.Substring(15) + $_.BaseName.Substring(11,4) }} | `
  Sort-Object -Property SortableName | Select-Object -Property FullName
0 голосов
/ 22 января 2020

Принятый ответ кажется отличным решением. Вот мой обновленный ответ, предоставляющий вам отсортированный массив [pscustomobjects] с включенными именами файлов, которые затем вы можете сослаться на свои имена с помощью $date_of_file.fileNM

$toImport = gci "server\folder\*"
$toImport = $toImport.fullname

$date_of_file = @()

foreach($item in $toImport){
    $date_of_file += [pscustomobject]@{
                      "fileNM" = $item;
                      "dispDate" = (split-path $item -leaf).substring(11,6);
                      "dateStamp"=  [datetime]::parseexact((split-path $item -leaf).substring(11,6),'MMddyy', $null)
                      }
    }

$date_of_file = $date_of_file | Sort-Object -Property dateStamp

$date_of_file.dispDate

---------- - Старый ответ ниже -----------

Это работает для меня:

$date_of_file = @()


$date_of_file +=  [datetime]::parseexact("010220", 'MMddyy', $null)
$date_of_file +=  [datetime]::parseexact("010320", 'MMddyy', $null)
$date_of_file +=  [datetime]::parseexact("010420", 'MMddyy', $null)
$date_of_file +=  [datetime]::parseexact("010520", 'MMddyy', $null)
$date_of_file +=  [datetime]::parseexact("120919", 'MMddyy', $null)


$date_of_file | Sort-Object {$_ -as [datetime]}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...