2015-04-16 4 views
-2

У меня есть файл, который выглядит следующим образом:Формат файла из текстового файла в Perl

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

я хотел бы, чтобы отформатировать его как этот

bob                  bill 
1427766557   12      1427762457   22 
1427769753   53 

Я не знаю, как подойти к это. Помоги пожалуйста.

+0

Пока ничего.Я пытаюсь это продумать. Должен ли я идти массив или хэш? Я думаю, что если я укажу в правильном направлении, я смогу разобраться. – user3718452

+2

Хеш хэшей: 'perldoc perldsc' – toolic

+1

Я думаю, вам нужно использовать хеш хэшей, и вам нужно перебирать каждый хэш в зависимости от количества элементов в хеше. И тогда вам нужно разработать логику печати. – Raghvendra

ответ

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; 
    } 
} 

должен делать эту работу.

НТН Джордж

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)[email protected]{$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; 
+1

++ Вы всегда можете попробовать ['Perl6 :: Form'] (http://www.metacpan.org/pod/Perl6::Form) для« сложной части »- но будьте осторожны: это привычка' form'- ing ;-) Немного похоже на ['IO :: All'] (https://metacpan.org/pod/IO::All) в этом отношении, что вы можете использовать read' $ csv'. –

2

Что вы уже пробовали?

ниже команда на самом деле не «один» лайнер - и это требует модуля 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 с именами Боба и Билла как хэш key и строку чисел как хэш value; то он печатает вещи, используя Perl6::Form (который действительно не нужен, но который я просто хочу рекламировать).

Выход:

bob       bill 
1427766557 12 | 1427762457 22 
1427769753 53 | 

выше может быть довольно легко превратить в сценарий, который падает в зависимость от form команды из Perl6::Format. Если вы это сделаете, разместите свою работу как дополнение/редактирование на свой вопрос или в виде отдельного ответа. Вы можете ответить на свой вопрос.

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... 
Смежные вопросы