• 締切済み

Perlでのテキスト処理について

Perlでのテキスト処理について質問です。 テキストファイルの中身が下記のようになっています。 【テキスト編集前】 --------------------------------------- test ,abc ,AB ,VI ,SS ,ma ---1行目 test ,abc ,AC ,PI ,VS ,ma ---2行目 test ,abc ,BA ,SS ,VS ,ma ---3行目 test ,abc ,BA ,VI ,VS ,ma ---4行目 test ,cde ,AA ,VI ,SS ,mb ---5行目 test ,cde ,CC ,PE ,VS ,mb ---6行目 test ,cde ,BC ,PI ,SS ,mb ---7行目 test ,cde ,AC ,PI ,SS ,mc ---8行目 --------------------------------------- 2列目(abc/cde)と6列目(ma/mb/mc)が同じ行に対しては 1行にまとめて出力したいと思っています。 この時、1列目、4列目、5列目はマージした形にし (同一文字は一度だけ出力、同一でない文字は/区切りで出力)、 2列目、6列目は同一文字をそのまま出力し、 3列目に関しては、該当する行の先頭行の文字列を 出力したいと思っています。 下記が当方の希望しているPerl実行後の出力結果です。 【テキスト編集後】 --------------------------------------- test ,abc ,AB ,VI/PI/SS ,SS/VS ,ma test ,cde ,AA ,VI/PE/PI ,SS/VS ,mb test ,cde ,AC ,PI ,SS ,mc --------------------------------------- このような編集をPerlで実行したいと思っているのですが、 どのような記述をすれば実行できるのか教えて頂けないでしょうか。 当方、Perlを始めたばかりで基本的なことを 伺っているのかもしれませんが すみませんが、ご了承ください。 宜しくお願いいたします。

みんなの回答

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.5

ところで普通はカンマの後ろに空白を置いて、前には置かないんじゃないですかね。 use strict; use warnings; use autodie; use v5.10; sub dump_data { my $data_ref = shift; given (ref($data_ref)) { when ("ARRAY") { say join(',', @{$data_ref}); } when ("HASH") { foreach my $e (sort keys %{$data_ref}) { dump_data($data_ref->{$e}); } } default { warn "invalid data"; } } } sub get_contents { my $fh; if (@ARGV) { open $fh, '<', shift @ARGV; } else { $fh = *DATA; } chomp(my @lines = <$fh>); close $fh; @lines; } #main my %data; foreach my $line (get_contents) { my @fields = split /\s*,\s*/, $line; if (exists $data{$fields[0]}{$fields[1]}{$fields[5]}) { my $ary_ref = $data{$fields[0]}{$fields[1]}{$fields[5]}; foreach my $i (0, 3, 4) { $ary_ref->[$i] .= "/$fields[$i]" if index($ary_ref->[$i], $fields[$i]) < 0; } } else { $data{$fields[0]}{$fields[1]}{$fields[5]} = \@fields; } } dump_data(\%data); __END__ test ,abc ,AB ,VI ,SS ,ma test ,abc ,AC ,PI ,VS ,ma test ,abc ,BA ,SS ,VS ,ma test ,abc ,BA ,VI ,VS ,ma test ,cde ,AA ,VI ,SS ,mb test ,cde ,CC ,PE ,VS ,mb test ,cde ,BC ,PI ,SS ,mb test ,cde ,AC ,PI ,SS ,mc

すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

個人的にはハッシュの方がいいかなと思ったり>#3.

すると、全ての回答が全文表示されます。
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.3

新規行を配列等に保存しておいて、2、6列目の同じ行が現れたら保存しておいた行を修正するというようなやり方があります。 use strict; my @result; NEXT: while (<DATA>) { my @line = split /[,\s]+/; foreach my $ref (@result) { if ($line[1] eq $$ref[1] and $line[5] eq $$ref[5]) { $$ref[0] .= "/$line[0]" if $$ref[0] !~ /\b$line[0]\b/; $$ref[3] .= "/$line[3]" if $$ref[3] !~ /\b$line[3]\b/; $$ref[4] .= "/$line[4]" if $$ref[4] !~ /\b$line[4]\b/; next NEXT; } } push @result, \@line; } print join(',', @$_), "\n" foreach @result; __DATA__ test ,abc ,AB ,VI ,SS ,ma test ,abc ,AC ,PI ,VS ,ma test ,abc ,BA ,SS ,VS ,ma test ,abc ,BA ,VI ,VS ,ma test ,cde ,AA ,VI ,SS ,mb test ,cde ,CC ,PE ,VS ,mb test ,cde ,BC ,PI ,SS ,mb test ,cde ,AC ,PI ,SS ,mc

すると、全ての回答が全文表示されます。
  • kabaokaba
  • ベストアンサー率51% (724/1416)
回答No.2

まあ,丸投げですなあ>No.1 こういうのって・・・他の人はどう作るかわからないけど 最低限 プログラムではなく手動でやるときにどうするのか? ってことが自分で整理できないと何もできないんだよね. 質問者は したい作業を手動でエディタでできるのかい? エディタでできるなら次にその工程を整理して 一個一個の作業を整理して 出来るかぎり小さな作業にばらして その小さな作業を一個一個プログラムにするとか そういうことができないのかな? そうすれば,自然とプログラム全体ができるし どこをコード化できないか切り分けもできるでしょう

すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

要するにスクリプト作成丸投げ?

すると、全ての回答が全文表示されます。

関連するQ&A