Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 导入平面文件固定宽度-建议_Perl_Powershell_Flat File_Fixed Width - Fatal编程技术网

Perl 导入平面文件固定宽度-建议

Perl 导入平面文件固定宽度-建议,perl,powershell,flat-file,fixed-width,Perl,Powershell,Flat File,Fixed Width,我正在读取一个平面文件(固定宽度字段),以便将其导入SQLServer。这是我公司的一个新项目。我还没有以最高效快捷的方式解析大型文件。在互联网上搜索,我发现了一个powershell脚本,它可以解析固定宽度的文件。。。它负责解析文件 [void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') $Parser = New-Object Microsoft.VisualBasic.FileIO

我正在读取一个平面文件(固定宽度字段),以便将其导入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)" 
} 
} 
我希望能够将其保存在管道分隔的文件中,这样我就可以简单地在sql数据库中使用BCP。这是我加载数据的快捷方式。但是,它使用了大量的时间(50000条记录需要20分钟)

任何快速/高效获取的建议:

  • 转换为以管道分隔的文件 或
  • 直接将平面文件从powershell导入SQL server。。。 或
  • 我愿意使用任何其他脚本语言,可以帮助在Windows下将平面文件快速解析为管道分隔文件(python、perl等)。如需使用任何示例脚本,将不胜感激

此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
您需要修改正则表达式和过滤器以匹配您的数据。我怀疑翻阅50万张这样的记录只需要不到20分钟的时间


-Readcount
通过在管道中一次只保留1000条记录来控制内存使用。它们将作为一个数组传递到管道,过滤器中的
-replace
操作符将在一次操作中对整个数组进行定界,而无需通过每个记录对每个
进行定界。
过滤器
是不寻常的,可以用每个对象的
替换,但是
过滤器
稍微快一点,如果你做了很多次重复,它就会累加起来。

你应该包括sample.dat文件和想要结果的sample(例如,你没有在上面的脚本中保存任何东西)。此外,决不能使用
写入主机
输出数据<代码>写入主机
用于文本,仅在交互式会话(控制台)中工作。只需使用
$Parser.ReadFields()
Write Output$Parser.ReadFields()
即可输出数据。@Graimer:我之所以没有发布任何示例数据,是因为我能够更好地解析数据而没有问题(因为数据按预期进行了解析)。这里是:
002722230415367691294302160A 102012-05-082012-06-143342731~0000000001929.51 39070000~1134117849~1750319562~2 2012-09-072012-09-09-10294302160A~~95 00307997040213600252581074647A 402013-03-252013-03-2913V5789~N 0000000.00 3930000031801884655~18570175~12013-05-032013-05-06281074647A~~00 0028707039287360025580907416A 402012-11-28012-11-281353510~000000000 1111.17
预期输出是管道分隔格式的相同数据。请共享一个使用写输出将数据保存到文件中的示例。Powershell不适用于处理此类卷中的数据。你知道其他编程语言吗?您已经用Perl和Python标记了您的问题。如果您可以使用这两种方法中的任何一种,那么您的程序将运行得非常快,这大概就是PowerShell?您应该这样说,并至少对代码提供一点注释。非常感谢。我想通过使用markdown来识别段落中的代码来完善它,但这非常好。这会接近Perl或Python的功能吗?@mjolinor:这太棒了。我可以在2分钟内浏览50000条记录。。。当我将输出重定向到文本时,50000条记录的时间不到30秒。在每行末尾写入一个静态数字(表示一个batchid)是一个什么快速/肮脏的修复方法?