• 締切済み

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を始めたばかりで基本的なことを 伺っているのかもしれませんが すみませんが、ご了承ください。 宜しくお願いいたします。

  • Perl
  • 回答数5
  • ありがとう数0

みんなの回答

  • 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

  • perlでのcsv形式のテキストファイルの変換

    perlを使用してcsv形式のテキストファイルを下記のように変換したいと思っています。 【変換前】 10, abc , def , ghi ,jkl    ----1行目 10, abc , def , aaa, bbb   ----2行目 10, abc , def , ccc , ddd  ----3行目 11, abc , def , eee , fff   ----4行目 11, abc , def , aaa , ggg ----5行目 11, zzz , def , aaa , ggg  ----6行目 12, abc , def , aaa ,ggg ----7行目 12, zzz , def, aaa , ggg   ----8行目 【変換後】 10, abc , def , ghi ,jkl    ----1行目 11, abc , def , eee , fff   ----4行目 11, zzz , def , aaa , ggg  ----6行目 12, abc , def , aaa ,ggg ----7行目 12, zzz , def, aaa , ggg   ----8行目 変換内容はcsv形式のテキストファイルで、”,”で区切った先頭3列が 前の行の先頭3列と同じならその行は出力しない、といった 変換をしたいと思っております。 (例えば2行目ですと先頭3列は10, abc ,defになっており、  1行目の先頭3列と同じ文字列になっているためこの行は出力しない) 当方、Perl初心者で上記のようなことがPerlでできるかも よくわかっておりません。 そこで、上記のような変換はPerlで可能なのか、そしてもし可能であるのなら どのようにPerlで記述すればできるのか教えていただけないでしょうか。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Perlでのテキスト変換方法に関して

    テキストファイルをperlを使用して下記のように 変換したいと思っています。 --------------------------- 【変換前】 aaa 8000 52 ---1行目 abc 200 48 ---2行目 cbd 250 31   ---3行目 efg 98 45   ---4行目 abc 390 68   ---5行目 ddd 89 90   ---6行目 aaa 65 40   ---7行目 fed 900 66   ---8行目 efgh 99 49 ---9行目 abc 40 40 ---10行目 【変換後】 aaa 8000 52   ---1行目 cbd 250 31   ---3行目 efg 98 45   ---4行目 abc 390 68   ---5行目 ddd 89 90   ---6行目 fed 900 66   ---8行目 efgh 99 49 ---9行目 ---------------------------- やりたいことはまず行の先頭文字列(aaaやabc)が完全に一致する行が 複数あれば(2,5,10行目のabcや1,7行目のaaa)、2番目の文字列(スカラー値)の値が 小さい方の行は出力しないようにしたいと思っています。 例えば上記の場合ですと、2,5,10行目の最初の文字列はaaaで完全に一致しており、 2番目の列の値は5行目が390に対し、2行目は200、10行目は40と小さくなっているため 2行目,10行目は出力されない、というのが望んでいる動作です。 sortを使用してどうにかならないかとも、考えたのですが そこから先がどうしていいか思いつきませんでした。 何かよい方法を思い浮かぶ方がいましたら、どのようにPerlで記述すればよいのか 教えて頂けないでしょうか? 宜しくお願いいたします。

    • ベストアンサー
    • Perl
  • linux テキスト処理

    お世話になります。 linuxのテキスト操作でご質問です。 (1) ------------------------- [root@*** ***]# vi test.txt 1 2 3 4 ------------------------ ↓ ↓ (2) -------------------------- [root@*** ***]# vi test.txt 1 2 3 4 ------------------------ 何百行もあるテキストデータを(1)⇒(2)に一発でできる方法は あるでしょうか? 以上、宜しくお願いいたします。

  • テキスト処理のシェルプログラム

    UNIXシェルもしくはPerlでテキスト処理のシェルスクリプト を作成したいのですがご教授お願いします 1000行あるテキストファイルを 2行単位で区切り2行単位で横一列へ置換しテキストへ出力したいのですが 例 処理前 aaa bbb ccc ddd eee fff 処理後 aaa,ccc,eee bbb,ddd,fff ご教授よろしくお願いします

  • perlで変数の中身を変数とみなす方法ってありますか?

    perlで、変数の中身を変数とみなし、その中身を知る方法ってありますか? 具体的に言うと、 $abc = "$xyz"; $xyz = "test"; なる状況だったとして、$abc から "test" という文字列にたどりつく 方法ってあるのでしょうか? 何をしたいのかというと、テキストファイル上に "$xyz" と書かれてたと します。そのテキストファイルを perl で解読したとき、その時点での 実行中の $xyz に何が入っているかを得たいのです。 もちろん、連想配列を使えば似たようなことができるのは知っていますが、 性質上、できればスタティック変数を使いたいのです。 そのような方法は、perl には用意されているのでしょうか?

    • ベストアンサー
    • Perl
  • Perl から csh 実行

    やまとです。 いつもありがとうございます。 Perl + csh を同時(?)に実行する方法を教えてください。 OSはSunです。 具体的にどのような処理を行いたいか簡単に説明しますと。 1.Perlでcshを実行(system関数?)し、cshで環境変数をセット(source)する。 2.cshで環境変数をセットしたら、ファイルを出力する処理が行われます。 3.Perlでcshによって出力されたファイルの内容を画面に表示します。 以下ソースを掲載します。(抜粋して) ================================================== = Perl ( test_perl.pl ) $data = "ABC"; $ret = system(`test_csh.sh $data`); ・ ・ ファイル(test.log)を開き、読込、画面に表示します(まだ作成してません。) ================================================== = Csh ( test_csh.sh ) source test_source.sh echo $1 > test.log ================================================== = test_source.sh setenv CLASSPATH .:/aaa・・・・・・ ↑ PATHの設定を行ってます。 ================================================== 画面に、「ABC」と出力させたいのです。 Perlからcshが実行されていないように思えるのですが、 Perlのsystem関数の使い方が誤っているのでしょうか? それとも、ClassPath等の設定をしなければならないのでしょうか? ちなみにコマンドから、 # test_csh.sh ABC と実行しますと、ファイルが出力され、かつ、sourceも実行されています。 Perlから実行する方法を教えてください。 説明が不十分であれば、補足いたしますのでご指摘ください。 宜しくお願いします。

    • ベストアンサー
    • Perl
  • htmlからテキストを返すperlを実行する方法

    アクセスカウンターの数字画像を出力するperlのcgiを、<img>タグで、 <img src="./counter.cgi"> と、呼び出す方法があると思いますが、これと同じように、画像ではなくテキストを出力するperlのcgiをhtml中に呼び出して、ブラウザに表示する方法はないでしょうか? 以下のような感じかと漠然と思ったのですが、やはり上手くいくはずはありませんでした。 ■cgiプログラム(test.cgi) #!/usr/bin/perl print "Content-type: text/plain\n\n"; print "TEST TEXT"; exit 0; ■htmlファイル <html><head></head> <body> <br> <hr> <object data="./test.cgi" type="text/plain"></object> <hr> </body> </html> perlもhtmlも独学で学んだ基礎レベルだと自分で思っています。 どなたか突破口となるヒントをお願いします。

    • ベストアンサー
    • Perl
  • Perlで一行で文字列の置き換え

    Perlでたとえば 文字列を$a = "abcdefg";を $a = "あdefg";と 先頭のabcをあに置き換える方法を1行の文で行いたいのですが可能でしょうか? 2行以上でなく、1行で済ませる方法です。 $b = "abcい";なら "あい"となってほしいです。

    • ベストアンサー
    • Perl
  • 行頭と行末に文字追加

    文字変換がうまくいきません。 sedとawkもしくはperlを使ってなんとかならないでしょうか? 行の行頭と行末を " で囲みたいのですが。 ------test.txt----- abc cde fgh hijk lm nopq rstu vwx y z ------test.txt---- 以下のように。 "abc cde fgh" "hijk lm" "nopq rstu vwx y z" よろしくお願いします。

    • ベストアンサー
    • Perl
  • perlについて、教えてください。

    perlについて、教えてください。 formからのデータを受け取り、ファイルに書き込んでいく、cgiプログラムを考えているのですが、 その際、ファイルに特定の文字列があった場合、その行を削除して、書き込むという事を行いたいです。 例)test.htmlのテキストボックスに、値を入力(name="a_text")。そして、x.cgiファイルで, 「name=a_text」を取得し、keep.cgiファイルに書き込む。 再度、test.htmlの入力値を受け取り、ファイルに書き込む際に、ファイルに「a_text」があれば、その行を削除してから、a_textの2回目の入力値を書き込みたいと考えています ご存知の方、ぜひ、ご教授下さい。 宜しくお願いします。

    • ベストアンサー
    • Perl

専門家に質問してみよう