2013-03-08 9 views
5

मेरे पास एक CSV फ़ाइल है जिसमें हेडर पंक्ति और डेटा से पहले टिप्पणी टेक्स्ट शामिल है, जिसे मैं आगे हेरफेर के लिए हैश के रूप में पढ़ना चाहता हूं। प्राथमिक कुंजी हैश हैश दो डेटा मानों का संयोजन होगा। मैं कैसे? शीर्ष लेख पंक्ति पैटर्न 'सूचकांक' चाबियाँ पर्ल सीएसवी हैश

  • फ़ाइल के बाकी हिस्सों में पढ़ें के लिए
  • उपयोग हैडर प्रयोग करने के लिए

    1. खोजें।

    उदाहरण सीएसवी

    # 
    # 
    # 
    # 
    Description information of source of file. 
    
    index,label,bit,desc,mnemonic 
    6,370,11,three,THRE 
    9,240,23,four,FOR 
    11,120,n/a,five,FIV 
    

    उदाहरण वांछित हैश

    ('37011' => { 'index' => '6', 'label' => '370', 'bit' => '11', 'desc' => 'three', 'mnemonic' => 'THRE'}, '24023' => {'index' => '9', 'label' => '240', 'bit' => '23', 'desc' => 'four', 'mnemonic' => 'FOR'}, '120n/a' => {'index' => '11', 'label' => '120', 'bit' => 'n/a', 'desc' => 'five', 'mnemonic' => 'FIV'}) 
    
  • उत्तर

    9

    आप उस के लिए Text::CSV मॉड्यूल की आवश्यकता होगी:

    #!/usr/bin/env perl 
    use strict; 
    use warnings; 
    use Data::Dumper; 
    use Text::CSV; 
    
    my $filename = 'test.csv'; 
    
    # watch out the encoding! 
    open(my $fh, '<:utf8', $filename) 
        or die "Can't open $filename: $!"; 
    
    # skip to the header 
    my $header = ''; 
    while (<$fh>) { 
        if (/^index,/x) { 
         $header = $_; 
         last; 
        } 
    } 
    
    my $csv = Text::CSV->new 
        or die "Text::CSV error: " . Text::CSV->error_diag; 
    
    # define column names  
    $csv->parse($header); 
    $csv->column_names([$csv->fields]); 
    
    # parse the rest 
    while (my $row = $csv->getline_hr($fh)) { 
        my $pkey = $row->{label} . $row->{bit}; 
        print Dumper { $pkey => $row }; 
    } 
    
    $csv->eof or $csv->error_diag; 
    close $fh; 
    
    +0

    [टेक्स्ट :: सीएसवी :: सरल] (https://metacpan.org/pod/Text::CSV:: सरल) इसे और भी आसान बनाता है। –

    3

    तुम हमेशा की तरह कुछ कर सकता है:

    #!/usr/bin/env perl 
    
    use strict; 
    use warnings; 
    
    my %hash; 
    while(<DATA>){ last if /index/ } # Consume the header 
    my $labels = $_; # Save the last line for hash keys 
    chop $labels; 
    while(<DATA>){ 
        chop; 
        my @a = split ','; 
        my $idx = 0; 
        my %h = map { $_ => $a[$idx++]} split(",", $labels); 
        $hash{ $a[1] . $a[2] } = \%h; 
    } 
    
    while(my ($K, $H) = each %hash){ 
        print "$K :: "; 
        while(my($k, $v) = each(%$H)) { 
         print $k . "=>" . $v . " "; 
        } 
        print "\n"; 
    } 
    
    __DATA__ 
    
    # 
    # 
    # 
    # 
    Description information of source of file. 
    
    index,label,bit,desc,mnemonic 
    6,370,11,three,THRE 
    9,240,23,four,FOR 
    11,120,n/a,five,FIV 
    
    +0

    मैं सहमत हूं ... यदि आप अपना इनपुट प्रारूप जानते हैं, तो अनगिनत मॉड्यूल और कोड की हजारों लाइनों को आमंत्रित करने की आवश्यकता नहीं है। –

    1

    सरल, pasteable पार्सर

    sub parse_csv { 
        my ($f, $s, %op) = @_; # file, sub, options 
        my $d = $op{delim}?$op{delim}:"\t"; # delimiter, can be a regex 
        open IN, $f; 
        $_=<IN>; chomp; 
        my @h=map {s/"//g; lc} split /$d/; # header assumed, could be an option 
        $h[0]="id" if $h[0] eq ""; # r compatible 
        while(<IN>) { 
         chomp; 
         my @d=split /$d/; 
         map {s/^"//; s/"$//;} @d; # any file with junk in it should fail anyway 
         push @h, "id" if (@h == (@d - 1)); # r compat 
         my %d=map {$h[$_]=>$d[$_]} (0..$#d); 
         &{$s}(\%d); 
        } 
    } 
    

    उदाहरण उपयोग:।

    parse_csv("file.txt", sub { 
        die Dumper $_[0]; 
    }) 
    

    टिप्पणी की तरह $ सामान, और $ _ अभी भी उप

    +0

    उत्कृष्ट कृति! क्या आप स्पष्टीकरण के कुछ शब्द दे सकते हैं, जैसे लाइन 'पुश @ एच, "आईडी" क्या है (@h == (@d - 1));' या लाइन 'और {$ s} (\% d);' कर? 'एलसी' क्या है? 'आर संगत' से आपका क्या मतलब है? – msciwoj

    1

    Text::CSV::Simple के बाद से ही अस्तित्व में है में काम करते हैं 2005 ...

    दस्तावेज़ों से:

    # Map the fields to a hash 
    my $parser = Text::CSV::Simple->new; 
    $parser->field_map(qw/id name null town/); 
    my @data = $parser->read_file($datafile); 
    

    ... आसान!