2013-12-21 4 views
-2

Я читаю плоский файл (поля фиксированной ширины), чтобы импортировать его в SQLServer. Это новый проект в моей компании. Я еще не работал над разбором огромных файлов самым быстрым и быстрым способом. Очистка в Интернете, я нашел сценарий powershell, который может анализировать файл с фиксированной шириной ... Он выполняет синтаксический анализ файла.Импорт плоской фиксированной ширины - предложения

[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') 

$Parser = New-Object Microsoft.VisualBasic.FileIO.TextFieldParser( 
'C:\T1046436.dat') 

$Parser.TextFieldType = 'FixedWidth' 
$Parser.TrimWhiteSpace = $False 
$Parser.FieldWidths = @(13,6,11,2,10,10,1,1,7,7,2,17,1,2,2,4,1,10,10,10,10,2,10,10,11,2,2,1,1) 

while(!$Parser.EndOfData) 
{ 
try 
{ 
    Write-Host $Parser.ReadFields() 
} 
catch [Microsoft.VisualBasic.FileIO.MalformedLineException] 
{ 
    Write-Host "Error, line $($_.Exception.LineNumber): $($Parser.ErrorLine)" 
} 
} 

Я хочу, чтобы иметь возможность сохранить это в трубчатой ​​табуляции, так что я могу просто BCP IN в SQL базы данных. Это мой быстрый-грязный способ загрузки данных. Но он использует много времени (20 минут для 50000 записей).

Любые предложения, чтобы получить его быстро/эффективно:

  • превращается в трубчатую табуляцией ИЛИ
  • непосредственно импортировать плоский файл в SQL сервер из PowerShell ... ИЛИ
  • Я открытые для использования любых других языков сценариев, которые могут помочь быстро разобрать плоский файл в файл с разделителями (python, perl и т. д.) под Windows. Любые примеры сценариев для использования будут оценены.
+0

Вы должны указать образец .dat-файла и образец желаемого результата (например, вы не сохраняете ничего в приведенном выше скрипте). Кроме того, вы никогда не должны использовать 'Write-Host' для вывода данных. 'Write-Host' предназначен для текста и будет работать только в интерактивных сеансах (консоли). Просто используйте '$ Parser.ReadFields()' или 'Write-Output $ Parser.Readfields()' для вывода данных. –

+0

@Graimer: Причина, по которой я не размещал никаких выборочных данных, поскольку я был более абсурдным для анализа данных без проблем (как в данных анализировалось, как ожидалось). Вот оно: '0027322230415367691294302160A 102012-05-082012-06-143342731 ~ 0000000001929,51 39070000 ~ 1134117849 ~ 1750319562 ~ 2 2012-09-072012-09-10294302160A ~ ~ 95 0030799704021360025281074647A 402013-03-252013-03-2913V5789 ~ N 0000000000000.00 3930000031801884655 ~ 1851370175 ~ 1 2013-05-032013-05-06281074647A ~ ~ 00 0028707039287360025580907416A 402012-11-282012-11-281353510 ~ 0000000001111.17' – DataRiver

+0

Ожидаемый результат - это те же данные в формате с разделителями каналов. – DataRiver

ответ

0

Этот сценарий Powershell будет анализировать коллекцию $ файлов, содержащих записи из 5 полей, каждая из которых имеет 10 символов, и выводит эти записи с полями, разделенными по строкам.

#Create a regular expression to match the field widths and capture the data. 
$regex = [regex]'(.{10})(.{10})(.{10})(.{10})(.{10})' 

#create a filter to insert a pipe character between the captured groups. 
filter PipeDelimit {$_ -replace $regex, '$1|$2|$3|$4|$5'} 


#Pipe the records thorough the filter in batches of 1000 
Get-Content $files -ReadCount 1000 | Pipedelimit 

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

-Readcount будет контролировать использование памяти, сохраняя только 1000 записей за раз в трубопроводе. Они будут переданы в конвейер в виде массива, а оператор -replace в фильтре разделит весь массив за одну операцию, без необходимости foreach через каждую запись. filter, по общему признанию, необычен и может быть заменен на foreach-object, но filter немного быстрее, и он добавляется, если вы делаете много повторений.

+0

Это, предположительно, PowerShell? Вы должны сказать так и дать хотя бы небольшой комментарий к коду. – Borodin

+0

ОК. Это лучше? – mjolinor

+0

Много. Спасибо. Я бы это прекратил, используя уценку, чтобы идентифицировать код в ваших параграфах, но это очень хорошо. – Borodin

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