从不同文件中拆分列

时间:2016-07-06 13:14:03

标签: perl

我想做自己的剧本,但我坚持不懈。它是如此微不足道,但这是我的第二个剧本。

我有几个文件。在每一个中,我有一个2列,第一个是常量值(它在整个文件数中),第三个是不同的。每个文件命名为:occ_CXX,其中XX是数字。 (我不需要第二栏)我的想法:

  1. 拆分整个文件数,而第一列对所有文件都是通用的,第二列等按顺序属于文件。 (我使用的是$ my_files = $ ARGV [0] - 从这里它只需要第一列,而$ my_pdb_files = $ ARGV [1] - 文件,所有文件都列在其中),但是我必须构造适当的循环到读取文件并将数字整理好。
  2. 此外,我想给出每个列的名称,它与名称中的数字相对应(occ_CXX - 我只对CXX感兴趣)。
  3. occ_CXX.dat文件如下所示:

      50000.000    1 291618
      50100.000    1 291618
      50200.000    0
      50300.000    1 115401
      50400.000    1 115401
    

1 个答案:

答案 0 :(得分:0)

通过对您的问题的描述以及您提供的一些评论,我认为下面的代码可能会产生您想要的内容。

我仍然不了解您如何访问这些文件。我不认为list.dat会让事情变得更容易。只是我的观点。我使用glob来获取occ_CXX.dat文件。

我在命令行上输入了目录。在该计划中,目录名称为shifted变量$dir

我的命令行是

perl test.pl .

' '是目录的名称。我使用dot,因为这些文件与我的程序位于同一目录中。如果您的程序从文件所在的不同目录运行,则必须在此处指定文件的目录或路径,而不是dot

更新:忽略了打印输出文件的位置。也就是说,到了什么目录。在这里,我只是将输出文件打印到与输入文件相同的目录。

更新2:更改

for my $col1 (sort keys %data)

for my $col1 (sort {$a <=> $b} keys %data)

(更新我的代码以进行此更改)

#!/usr/bin/perl
use strict;
use warnings;

my $dir = shift; # get directory from @ARGV (on the command line)

my @occ_files = sort by_number glob "$dir/occ_C*.dat";

my @headers = map /_(C\d+)/, @occ_files;

my %data;

for my $file (@occ_files) {
    open my $fh, '<', $file or die "Can't open $file $!";

    $file =~ /_(C\d+)/;
    my $col_head = $1;

    while (<$fh>) {
        my ($col1, undef, $col3) = split;
        $data{$col1}{$col_head} = $col3 || '';
    }
    close $fh or die "Can't close $file $!";
}

my $format = "%-15s" . "%-10s" x (@headers-1) . "%s\n";

my $new_file = "$dir/occ_sub.dat";
open my $out, '>', $new_file or die "Can't open $new_file $!";

printf $out $format, '', @headers;

for my $col1 (sort {$a <=> $b} keys %data) {
    printf $out $format, $col1, @{ $data{$col1} }{@headers};    
}

sub by_number {
    my ($a_num) = $a =~ /_C(\d+)\.dat/;
    my ($b_num) = $b =~ /_C(\d+)\.dat/;
    $a_num <=> $b_num;
}

这创建了一个带有此输出的文件(使用2个示例输入文件):

               C01       C02
50000.000      291618    58902
50100.000      291618    58902
50200.000                58902
50300.000      115401    58902
50400.000      115401    58902
50500.000      115401    58902
50600.000      115401    58902
50700.000      115401    58902
50800.000      291618
50900.000      291618    58902
51000.000      291618    58902
51100.000      291618    58902
51200.000      291618    58902
51300.000      291618    58902
51400.000      291618    58902
51500.000      291618    58902
51600.000      291618    58902
51700.000      291618    58902
51800.000      291618
51900.000      291618    58902
52000.000      291618    58902
52100.000      291618    58902
52200.000      291618    58902
52300.000      291618    58902
52400.000      291618    58902
52500.000      291618    58902
52600.000      291618    58902
52700.000      291618
52800.000      291618    58902
52900.000      291618    58902
53000.000                58902
53100.000      291618    58902
53200.000      291618    58902