从Perl中的文本文件格式化文件

时间:2015-04-16 23:39:48

标签: perl

我有一个看起来像这样的文件:

12,1427766557, bob 
22,1427762457, bill 
53,1427769753, bob 

我想像这样格式化它

bob                  bill 
1427766557   12      1427762457   22 
1427769753   53 

我不确定如何处理这个问题。请帮助。

4 个答案:

答案 0 :(得分:2)

类似的东西:

use strict;
my %data;
while (my $line = <>) {
    $line =~ s/\s+//g;
    my ($n1, $n2, $name) = split(/\s*,\s*/,$line);
    push @{$data{$name}}, [$n2, $n1];
}

foreach my $name (keys %data) {
    print "$name\t\t\t";
}
print "\n";

my $count =0;
my $found=1;
while ($found) {
    $found=0;
    my $line = '';
    foreach my $name (keys %data) {

        if ($#{$data{$name}}>= $count) {
            $found +=1 ;
            $line .=sprintf ("%10d\t%2d\t",@{$data{$name}[$count]});
        } else{
            $line .="           \t  \t";
        }
    }
    if($found) {
        print "$line\n";
        $count += 1;
    }
}

应该做的。

HTH 乔治

答案 1 :(得分:2)

你有什么尝试?

下面的命令实际上不是一个&#34;一个&#34;衬里 - 它确实需要一个CPAN模块(Perl6::Form - 它可能只被称为Perl::Form并包含在perl中),但它可以快速剪切并粘贴,如果你已经有安装模块。

perl -e '(my @DATA = qq/12,1427766557, bob
22,1427762457, bill
53,1427769753, bob/);
@DATA = map { [ split/,\s*/ ] } map { chomp;  split/\n/ } @DATA;
push @{ $hash{ $_->[2] } } , "$_->[1] $_->[0]" for @DATA;
@header = keys %hash ;
@data = values %hash ;
use Perl6::Form;
print form
"{[[[[[[[[[[[[}   {[[[[[[[[[[[[[[[[}", @header,
"{[[[[[[[[[[[[} | {[[[[[[[[[[[[[[[}", @data ;'

该命令将原始数据存储在名为@DATA的数组/列表中(而不是从文件读取或将其放入脚本的__END____DATA__);然后将map用于split,将push用于%hash,将Bob和Bill的名称作为哈希key和字符串数字作为哈希value;然后它使用Perl6::Form打印出来的东西(这不是真正需要的,但我只想做广告)。

<强>输出

bob                          bill
1427766557 12  | 1427762457 22
1427769753 53  |

以上内容可以很容易地转换为一个脚本,从而放弃了对form Perl6::Format命令的依赖。如果您这样做,请将您的工作作为附录/编辑发布到您的问题或作为单独的答案。你可以在SO上回答你自己的问题。

答案 2 :(得分:1)

这是一种方法。此代码假定您的文件名为test.csv。

use v5.10;
use boolean;
use strict;
use warnings;  
use Text::CSV;

my $csv = new Text::CSV; 
open(my $f, "<", "test.csv") or die "Can't open file: $!";  
my %numbers_by_name; #hash to hold the data, keyed by name
##
#  read in each line of the file and store each unique line for each 
#  name in the hash
##
while(my $row=$csv->getline($f)){
    my ($num0, $num1, $name)=@{$row};  
    if($numbers_by_name{$name}){
        push @{$numbers_by_name{$name}}, [$num1, $num0]; 
    }
    else{
        $numbers_by_name{$name}=[];  
        push @{$numbers_by_name{$name}}, [$num1, $num0]; 
    }   
}  

##
#  print the header row of names
##
my $num_keys=keys %numbers_by_name;
my $tabs="\t" x $num_keys; 
say join($tabs,keys %numbers_by_name);

##
# the trickier part is formatting the lines of output
##
my $line;
my $i=0;
my $j=1;   
while($i < $j){
    my $more=false;  
    for my $k (keys %numbers_by_name){
        if($numbers_by_name{$k}){
            if($numbers_by_name{$k}->[$i]){
                $line.=join(" ",@{$numbers_by_name{$k}->[$i]});   
            }
        }
        $line.="\t"; 
        if($numbers_by_name{$k}->[$j]){
            $more=true;   
        }
    }
    $line.="\n"; 
    if($more){
        $i=$j;
        $j++;
    }  
    else{
        $i=$j;
    }
}

print $line; 

答案 3 :(得分:0)

enter code here这就是我现在所拥有的。

所以我的哈希键包含数组的第三个元素,值是数组的其他2个元素。

12,1427766557,鲍勃

5,1427766556,账单

10,1427766555,鲍勃

my %data;
open(DATA, "<", "test.csv") or die "Can't open file: $!";
while (my $row=<DATA>) {
  @$_ = split /(?:,|\s)+/, $row;
  $#$_!=2 ? next : push @{$data{$_->[2]}}, @$_[1,0]
}

我只需要阅读它,以便它看起来像这样。请帮忙?我希望将其导出为CSV文件。

         name        name       name
 time    value       value      value
 time    value       value      value
 etc...