2014-03-18 85 views
-1

道歉,如果這是一個長長的囉嗦,我真的很感謝這裏的答案,因爲我很難得到這個工作。perl +讀取多個csv文件+操作文件+提供output_files

從這個問題構建here,我有這個腳本在csv文件(orig.csv)上工作,並提供我想要的csv文件(format.csv)。我想要的是使其更通用,並接受任意數量的'.csv'文件,併爲每個輸入文件提供'output_ csv'。誰能幫忙?

#!/usr/bin/perl 

    use strict; 
    use warnings; 

    open my $orig_fh, '<', 'orig.csv' or die $!; 
    open my $format_fh, '>', 'format.csv' or die $!; 

    print $format_fh scalar <$orig_fh>; # Copy header line 

    my %data; 
    my @labels; 

    while (<$orig_fh>) { 
     chomp; 
     my @fields = split /,/, $_, -1; 
     my ($label, $max_val) = @fields[1,12]; 
     if (exists $data{$label}) { 
     my $prev_max_val = $data{$label}[12] || 0; 
     $data{$label} = \@fields if $max_val and $max_val > $prev_max_val; 
     } 
     else { 
     $data{$label} = \@fields; 
     push @labels, $label; 
     } 
    } 

    for my $label (@labels) { 
     print $format_fh join(',', @{ $data{$label} }), "\n"; 
    } 

我希望能使用來自here這個腳本但我有很大的困難,把2一起:

#!/usr/bin/perl 
    use strict; 
    use warnings; 
    #If you want to open a new output file for every input file 
    #Do it in your loop, not here. 
    #my $outfile = "KAC.pdb"; 
    #open(my $fh, '>>', $outfile); 
    opendir(DIR, "/data/tmp") or die "$!"; 
    my @files = readdir(DIR); 
    closedir DIR; 
    foreach my $file (@files) { 
    open(FH, "/data/tmp/$file") or die "$!"; 
    my $outfile = "output_$file"; #Add a prefix (anything, doesn't have to say 'output') 
    open(my $fh, '>', $outfile); 
    while (<FH>) { 
    my ($line) = $_; 
    chomp($line); 
    if ($line =~ m/KAC 50/) { 
    print $fh $_; 
    } 
    } 
    close($fh); 
    } 

腳本讀取目錄中的所有文件,並找到符合這個字符串「 KAC 50',然後將該行附加到該inputfileoutput_$file。所以會有1 output_$file對於每個被讀這個劇本,我已經注意到

問題inputfile並一直在尋找解決: - 它會讀取「」和'..'文件併產生一個 'output_'。和'output_ ..'文件 - 它也會對此腳本文件執行相同的操作。

我還試圖使它的動態通過獲取這個腳本在它通過添加該代碼在任意目錄下工作:

use Cwd qw(); 
my $path = Cwd::cwd(); 
print "$path\n"; 

opendir(DIR, $path) or die "$!"; # open the current directory 
open(FH, "$path/$file") or die "$!"; #open the file 

**編輯::我曾嘗試結合版本,但我得到errors.Advise不勝感激*

[email protected] ~/Perl 
$ perl formatfile_QforStackOverflow.pl 
Parentheses missing around "my" list at formatfile_QforStackOverflow.pl line 13. 
source dir -> /home/UserName/Perl 
Can't use string ("/home/UserName/Perl/format_or"...) as a symbol ref while "strict refs" in use at formatfile_QforStackOverflow.pl line 28. 

組合代碼::

use strict; 
    use warnings; 
    use autodie; # this is used for the multiple files part... 

    #START::Getting current working directory 
    use Cwd qw(); 
    my $source_dir = Cwd::cwd(); 
    #END::Getting current working directory 

    print "source dir -> $source_dir\n"; 
    my $output_prefix = 'format_'; 

    opendir my $dh, $source_dir; #Changing this to work on current directory; changing back 

    for my $file (readdir($dh)) { 
     next if $file !~ /\.csv$/; 
     next if $file =~ /^\Q$output_prefix\E/; 

     my $orig_file = "$source_dir/$file"; 
     my $format_file = "$source_dir/$output_prefix$file"; 

     # .... old processing code here ... 
     ## Start:: This part works on one file edited for this script ## 
     #open my $orig_fh, '<', 'orig.csv' or die $!; #line 14 and 15 above already do this!! 
     #open my $format_fh, '>', 'format.csv' or die $!; 

     #print $format_fh scalar <$orig_fh>; # Copy header line #orig needs changeing 
     print $format_file scalar <$orig_file>; # Copy header line 

     my %data; 
     my @labels; 

     #while (<$orig_fh>) { #orig needs changing 
     while (<$orig_file>) { 
      chomp; 
      my @fields = split /,/, $_, -1; 
      my ($label, $max_val) = @fields[1,12]; 
      if (exists $data{$label}) { 
      my $prev_max_val = $data{$label}[12] || 0; 
      $data{$label} = \@fields if $max_val and $max_val > $prev_max_val; 
      } 
      else { 
      $data{$label} = \@fields; 
      push @labels, $label; 
      } 
     } 

     for my $label (@labels) { 
      #print $format_fh join(',', @{ $data{$label} }), "\n"; #orig needs changing 
      print $format_file join(',', @{ $data{$label} }), "\n"; 
     } 
     ## END:: This part works on one file edited for this script ## 

    } 

回答

0

你打算如何在輸入文件處理和他們首選的輸出目的地的名單?也許只是有一個固定的目錄,你想要處理所有的CVS文件,並以結果爲前綴。

#!/usr/bin/perl 

use strict; 
use warnings; 
use autodie; 

my $source_dir = '/some/dir/with/cvs/files'; 
my $output_prefix = 'format_'; 

opendir my $dh, $source_dir; 
for my $file (readdir($dh)) { 
    next if $file !~ /\.csv$/; 
    next if $file =~ /^\Q$output_prefix\E/; 

    my $orig_file = "$source_dir/$file"; 
    my $format_file = "$source_dir/$output_prefix$file"; 

    .... old processing code here ... 

} 

或者,您可以只有一個輸出目錄而不是前綴文件。無論哪種方式,這應該讓你在路上。

+0

對不起,我認爲這很清楚,我只是將格式化的文件保存在同一目錄中,但他們會有一個前綴來區分。這是否是一種好的做法? tks – HattrickNZ

+0

只要你正確地編寫代碼,這是一個很好的練習。我所展示的你將完成大部分工作。你最終需要學習更多的編程技巧,而不是把論壇上其他人提供的代碼拼湊在一起。祝你好運。 – Miller

+0

仍然出現錯誤,將不勝感激您的建議,編輯我的Q,tks – HattrickNZ