2011-02-06 20 views
8

मैं निश्चित-चौड़ाई क्षेत्रों के साथ पाठ फ़ाइलों का एक बहुत कुछ है:पार्स निश्चित-चौड़ाई फ़ाइलों

<c>  <c>  <c> 
Dave Thomas 123 Main 
Dan  Anderson 456 Center 
Wilma Rainbow 789 Street 

फ़ाइलों के बाकी एक समान प्रारूप, जहां <c> एक कॉलम की शुरुआत का प्रतीक होगा में हैं, लेकिन उनके पास विभिन्न (अज्ञात) कॉलम & स्पेस चौड़ाई हैं। इन फ़ाइलों को पार्स करने का सबसे अच्छा तरीका क्या है?

मैं Text::CSV उपयोग करने की कोशिश, लेकिन कोई सीमांकक है क्योंकि यह (जब तक मैं मॉड्यूल गलत उपयोग कर रहा हूँ) एक सुसंगत परिणाम प्राप्त करना मुश्किल है:

my $csv = Text::CSV->new(); 
$csv->sep_char (' '); 

while (<FILE>){ 
    if ($csv->parse($_)) { 
     my @columns=$csv->fields(); 
     print $columns[1] . "\n"; 
    } 
} 
+1

आप "पार्सिंग" टैग पर ऑब्जेक्ट क्यों करते हैं? यह एक पार्सिंग समस्या है। आपको पर्ल में एक समाधान की आवश्यकता है इसका मतलब यह नहीं है कि यह एक पार्सिंग समस्या नहीं है। – zwol

+0

क्योंकि मैं सामान्य समाधान –

+0

नहीं चाहता हूं, शायद मुझे गलत समझा जाए ... मैंने सोचा था कि वहां "पार्सिंग" डालने से समाधान की पूरी गुच्छा आएगी जो मेरी स्थिति (यानी पायथन, पीएचपी, आदि) से प्रासंगिक नहीं हैं .. ..thx –

उत्तर

12

उपयोगकर्ता 604939 उल्लेख के रूप में, unpack निश्चित चौड़ाई वाले फ़ील्ड के लिए उपयोग करने का टूल है। हालांकि, unpack के साथ काम करने के लिए एक टेम्पलेट पारित करने की जरूरत है। के बाद से आप कहते हैं कि अपने क्षेत्रों चौड़ाई बदल सकते हैं, समाधान आपके फ़ाइल की पहली पंक्ति से इस टेम्पलेट का निर्माण करना है:

my @template = map {'A'.length}  # convert each to 'A##' 
       <DATA> =~ /(\S+\s*)/g; # split first line into segments 
$template[-1] = 'A*';     # set the last segment to be slurpy 

my $template = "@template"; 
print "template: $template\n"; 

my @data; 
while (<DATA>) { 
    push @data, [unpack $template, $_] 
} 

use Data::Dumper; 

print Dumper \@data; 

__DATA__ 
<c>  <c>  <c> 
Dave Thomas 123 Main 
Dan  Anderson 456 Center 
Wilma Rainbow 789 Street 

जो प्रिंट:

 
template: A8 A10 A* 
$VAR1 = [ 
      [ 
      'Dave', 
      'Thomas', 
      '123 Main' 
      ], 
      [ 
      'Dan', 
      'Anderson', 
      '456 Center' 
      ], 
      [ 
      'Wilma', 
      'Rainbow', 
      '789 Street' 
      ] 
     ]; 
+0

@random_months_later_downvoter => कहने की देखभाल क्यों? –

3

बस पर्ल के unpack समारोह का उपयोग करें। कुछ इस तरह: खोल टेम्पलेट, "एक ###" इनसाइड

while (<FILE>) { 
    my ($first,$last,$street) = unpack("A9A25A50",$_); 

    <Do something ....> 
} 

, आप प्रत्येक ए के लिए क्षेत्र की चौड़ाई डाल सकते हैं अन्य प्रारूपों कि आप मिश्रण का उपयोग कर सकते की एक किस्म कर रहे हैं और मिलान करें, यानी, पूर्णांक फ़ील्ड, आदि ... यदि फ़ाइल निश्चित चौड़ाई है, जैसे मेनफ्रेम फ़ाइलों की तरह, तो यह सबसे आसान होना चाहिए।

+0

जो मेरे प्रश्न का हिस्सा है ... फ़ील्ड की चौड़ाई उस फ़ाइल के आधार पर बदल जाएगी जो मैं इसे खिलाता हूं। क्या हेडर से चौड़ाई का पता लगाने के लिए अनपैक करने का कोई तरीका है? –

6

बचाव के लिए CPAN!

DataExtract::FixedWidth न केवल फिक्स्ड-चौड़ाई वाली फाइलों को पार करता है, लेकिन (पीओडी के आधार पर) हेडर लाइन से कॉलम चौड़ाई को समझने के लिए पर्याप्त स्मार्ट लगता है!

+0

+1 उत्तर दिया गया :-) –

+0

बीटीडब्ल्यू, लेखक थोड़ी देर में एसओ पर यहां लटकता है। – DVK

+0

डीवीके ++ =) धन्यवाद! डीई: एफडब्ल्यू का परीक्षण [टन परीक्षण इनपुट] के साथ भी किया जाता है। (Http://api.metacpan.org/source/ECARROLL/DataExtract-FixedWidth-0.09/t/data/) –

संबंधित मुद्दे