Объединение нескольких файлов .csv в один с помощью PowerShell - GetChildItem очень медленный (так как в каталоге более 4000 файлов) - PullRequest
0 голосов
/ 26 сентября 2019

Я пишу сценарий в PowerShell, который будет получать файлы из общей папки в течение определенного периода времени (в этом случае между сегодняшней датой в 8:00 и вчерашней датой в 6:00 - согласно логикефайлы, это будет около 14 файлов в этот период времени).То, что я делаю, чтобы достичь этих конкретных файлов среди других 4000+ .csv файлов, получает их «Имя файла» и сравнивает с этим правилом конкретного периода.

Пример имени файла: «2019.09.17-06.00.OutPutAXIS "

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

Например,

HEADER (Gotten from the first file)
1 FILE DATA (Gotten from the first file)
2 FILE DATA (Gotten from the second file)
3 FILE DATA (Gotten from the third file)
and so on...

Проблема в том, что для ее завершения требуется около 50 минут.Я читал статьи о том, что cgi действительно медленный, но я не смог найти другую замену, которая бы сработала.

Несколько попыток и поиск на моей стороне:

PowershellGet-ChildItem самый последний файл в каталоге

Объединение нескольких файлов CSV в один с помощью PowerShell

https://www.reddit.com/r/PowerShell/comments/51q9s5/getchilditem_ist_very_slow_when_dealing_with_a/

https://devblogs.microsoft.com/powershell/why-is-get-childitem-so-slow/

<# Элементы, которые получают временные рамки и имена файлов для последующего сравнения в коде: #>

$Today_Date = [DateTime]::Today.AddHours(8).ToString("yyyy.MM.dd-hh.mm")
$Yesterday_Date = 
[DateTime]::Today.addDays(-1).AddHours(6).ToString("yyyy.MM.dd-hh.mm")
[array]$Name_Files = [System.IO.Directory]("$IN_FILE_PATH\*.csv") | Where- 
Object {$_.LastWriteTime -gt (Get-Date).AddDays(-2)} | Select-Object - 
ExpandProperty BaseName

<# Я добавил эту часть "LastWriteTime", чтобы по крайней мереон ищет файлы более определенным образом, файлы за 2 дня до этого будут около 30 (они составляют от 200 до 5 КБ, это действительно зависит, но они действительно имеют небольшой размер). </p>

Функция, котораяотделяет файлы, которые соответствуют временным рамкам, от других, затем добавляет в папку, в которую они будут объединены. #>

foreach ($name in [array]$Name_Files -replace ".OutPutAXIS", "") {
        if (($name -ge $Yesterday_Date) -AND ($name -le $Today_Date)) {
                Move-Item -path "$IN_FILE_PATH\$Name.csv" -destination "$MERGING_FILE_PATH" 
///
}

Само объединение:

try {
    if ($getFirstLine = $true) {
        get-childItem "$MERGING_FILE_PATH\*.csv" | ForEach {
            $filePath = $_

            $lines = $lines = Get-Content $filePath
            $linesToWrite = switch ($getFirstLine) {
                $true { $lines }
                $false { $lines | Select -Skip 1 }
            }
            #Import all the information and tranfer to the new workbook.
            $Report_name = $((get-date).ToString("yyyy.MM.dd-hh.mm"))

            $getFirstLine = $false
            Add-Content "$OUT_FILE_PATH\Report $Report_Name.csv" $linesToWrite  
        }
    }
    $LogDate = (Get-Date).ToString("dd-MMM-yy hh:mm:ss")
    $Log += $LogDate + " - SUCCESS: Successfully retrieved all data from the .csv files and merged to create the report."
}#try end

catch {
    $LogDate = (Get-Date).ToString("dd-MMM-yy hh:mm:ss")
    $Log += $LogDate + " - FAILED: Error while trying to process the report. Could not retrieve all the data and/or merge the .csv files." + $_.Exception.ToString 
}#catch end

Работает,но мне нужно, чтобы производительность была намного быстрее.Я новичок в PowerShell, поэтому я не мог придумать лучшего пути к этому.Если бы это заняло около 5 минут, было бы здорово.

1 Ответ

0 голосов
/ 27 сентября 2019

Если CGI медленный для вас, обратите внимание на использование параметра -Filter.Фильтрация объекта where будет оценивать каждый элемент в вашем каталоге по заданным критериям, тогда как -Filter - нет.

...