2013-11-25 30 views
1

我有了在頭一些額外的線路,並在年底最後一行csv文件,像這樣:在CSV解析額外的線路文件

!ReleaseDate:20131120 
!id|AssetIDType|AssetID|StartDate|EndDate 
ARGAAA1|CINS|P00879117|19860131|20090323 
ARGAAA1|CUSIP|P00879117|19860131|20090323 
...... 
ZIMADQ1|SEDOL|B7W9VC2|20121008|20751231 
[End of File] 

我想用文字來解析它:: CSV_XS。

  1. 有沒有辦法擺脫第一線? (我想我可以跳過它)
  2. 以第二行作爲列名(跳過第一個「!」)
  3. 閱讀直到我得到[文件結束],這是一個字符串,而不是EOF符號?

回答

2

您可以執行以下操作:在您的數據集

use strict; 
use warnings; 
use Text::CSV_XS; 

my $csv = Text::CSV_XS->new({ binary => 1, auto_diag => 1, sep_char => '|' }); 

open my $fh, "<:encoding(utf8)", 'File.csv' or die "File.csv: $!"; 

while (my $row = $csv->getline($fh)) { 
    next if $row->[0] =~ /^!|\[/; 
    print $row->[2], "\n"; 
} 

close $fh; 

輸出:

P00879117 
P00879117 
B7W9VC2 

這得到了next線,如果當前以字符開始(或字符集),你止跌在第一欄找不到。

希望這會有所幫助!

+0

這是我詢問的大部分內容,它不會自動讀取列名(第2個問題)。 –

2

有沒有辦法擺脫第一線? (我想我可以跳過它)

您似乎檢查開始!線,或者只是跳過第一行,如果你的文件格式非常有信心。

乘坐二號線列名(跳過第一個!)

你可以閱讀getline標題行,然後用getline_hr讀取文件的其餘部分之前通過數組引用到column_names產生的。該模塊的文檔提供了一個例子是這樣的:如果你打算在數據很多閱讀

my @cols = @{$csv->getline($io)}; 
$csv->column_names(@cols); 
while (my $row = $csv->getline_hr($io)) { 
    print $row->{price}; #this assumes there is a 'price' field 
} 

,你可以用bind_columns優化,再次使用從模塊的文檔的例子。

閱讀直到我得到[文件結束]?

從上面的代碼片段可以看出,while循環會執行這個技巧。一旦你到達文件末尾,各種getline函數將返回undef或其他一些假值,這將終止循環。

+0

[文件結束]不是EOF符號,它是一個字符串。而第二行有「!」在它前面簽名,所以bind_columns可能會將其作爲名稱的一部分 –

+1

@RomanHoyenko您可以**輕鬆地**爲您的任務調整rutter的代碼。要從列名稱中去除前導'!',在調用'$ csv-> column_names(@cols)'前更新'@ cols'。你可以在while循環中檢查你的魔術'[End of File]'字符串,如果你點擊它,退出循環。 – ThisSuitIsBlackNot

+0

我認爲$ csv-> getline_hr($ io)在獲取[文件結束]時會失敗。我希望它在不正確的行上失敗,但不在這一行上。 –