• 締切済み

項目の比較

perlでタブ区切りのテキストデータに、タイトルと文章が入っているとします。 タイトルのは同じタイトルのものが重複していますが、種類は5種類ぐらいです。 ここで、タイトルの名前が変わった時一回だけ、見出しの様な感じで出力したいんですが、(要するに重複しているタイトルは出力せず、文章は重複していないので全て出力したいです。) 初心者の為よく分かりません。 とりあえず、項目分割して単純に出力する事は出来ます。 項目の重複をどのようにしたら調べられるのか教えて下さい; 初歩的な事ですが、どなたか分かる方いましたらお願いします。

みんなの回答

noname#9431
noname#9431
回答No.4

タイトルは 文書番号 年代 作成者 大項目 中項目 01 享保9甲辰年 不明 一 1 02 文化14丁丑年 不明 一 1 03 (文久元酉年11月) 奉行 二 1 04 文久元年酉11月 奉行 二 2 の様に、 文書番号、 年代 、作成者 、大項目、 中項目、 の5つから成るとします。 (コードには小項目などもあるようでしたが無視しました。) 重複しているタイトルは出力しないという場合の 「重複判断」の規準がご説明だけからははっきりしなかったので、 5つの項目の内1つでも一致してたら「重複している」という判断とします。 一致は完全な一致です。だから、 (文久元酉年11月) と 文久元年酉11月 とでは かっこの文だけ異なるのでこの項目に関しては「異なる」と判断します。 このとき、重複のないタイトルだけを表示するには 以下の様にするといいかもしれません。 ただし、補足いただいたのコードではデータはもっと多くの項目からなっていて タイトルはその一部をとったもののようですが、 いまは、データファイルには5つのフィールドしかないという下で考えてます。 >文章は重複していないので全て出力したい の部分は補足の内容だけからはよく意味がわからなかったので、 (データファイルのどの位置に「文章」があるのか等) 無視しました。 #!/usr/bin/perl -w use strict; open (IN,"test.txt"); my @last_title=(0 .. 4); while (<IN>) { chomp; my @title=split(/\s/); { my $term; for ($term=0; $term < @title; $term++){ last if ( $title[$term] eq $last_title[$term]) ; } if ($term == @title) { print $_,"\t" foreach @title; print "\n"; @last_title=@title; } } } close(IN);

noname#9431
noname#9431
回答No.3

すみません。2度同じことを書いてしまいました。 消し忘れです。 説教臭くなってすみません。。。

paraiso1210
質問者

お礼

>説教臭くなってすみません。。。 とんでもないです!わかりにくい説明で申し訳ないです;ご丁寧にありがとうございます。 一応下に自分で書いたものを載せました。 たぶん間違いだらけだと思います; こんなんでショボくて申し訳ないですが、コメントいただけると助かります!

paraiso1210
質問者

補足

文書の種類としては、歴史の資料の様なものです。 文書番号 年代 作成者 大項目 中項目 01 享保9甲辰年 不明 一 1 02 文化14丁丑年 不明 一 1 03 (文久元酉年11月) 奉行 二 1 04 文久元年酉11月 奉行 二 2 といった感じです。 大項目などのタイトルが重複しています。それぞれ一回だけ出力したいのです。 自分で書いたものは以下のものです。 途中までしか書けてない上に説明下手で申し訳ありません; while (<IN>) { # 項目分割する @IN = split(/\t/); $nunber = $IN[0]; $nendai = $IN[2]; $sakusei = $IN[3]; $daik = $IN[7]; $chuk = $IN[8]; $syok = $IN[9]; $komidasi = $IN[10]; # 見出し名が変わったら出力 if(){ my %count; @array = grep(!$count{$_}++, @array); } &SYUTURYOKU; } # 出力用サブルーチン sub SYUTURYOKU{ printf(OUT "$nunber\t$nendai\t$sakusei\t$daik\t$chuk\t$syok\t$komidasi\n"); } # ファイルを閉じる close(IN); close(OUT); こんな感じで分かりますでしょうか?

noname#9431
noname#9431
回答No.2

質問の内容が少々くみ取りにくいのですが、 (技術系の質問ではやりたいことを具体的に書いた方がよりよい解答がえられるとおもいます。また、自分の書いたコードもあわせて書いて頂けるとなにが問題か回答者が理解するたすけにもなります。) title1 content1 title1 content2 title2 content3 title3 content4 title3 content5 の内容を(タブ区切り)(test.txt) title1 content1 content2 title2 content3 title3 content4 content5 と表示したいのだと理解します。 この場合、例えば、 #!/usr/bin/perl -w use strict; open (IN,"test.txt"); my $last_title=""; while (<IN>) { chomp; my ($title, $content) = split(/\t/,$_); if ( $title ne $last_title) { print "$title\n"; $last_title=$title; } print "$content\n"; } close (IN); こんなのでできます。 あくまで一例です。解答というより、自分の練習のために書きました。 # 技術系の質問では、やりたいことをもう少し具体的に書いた方がよりよい解答が得られると思いますよ。また、自分の書いたコードもあわせて書いた方が、何が問題か回答者が理解する助けにもなると思います。 ご参考まで~

回答No.1

こんな感じでしょうか? テストしていないので動くかどうかはわかりませんが参考までに if ($title == $save_title) { //退避していた内容と同じであれば空出力  echo " \n"; }else{ //退避していた内容と違っていればタイトル出力  echo "$title\n";  $save_title = $title }

paraiso1210
質問者

お礼

早速のご回答ありがとうございます。 $save_titile 「退避していた内容~」というのは、もう一つ同じファイルを作ってそれを比較すると言う事でしょうか??よく分かってなくてすみません; if~else文を使えばいいのは、何となく分かっていたんですが、項目をどうやって比較したらいいのかよく分からないです; 項目を一行ずつ読み込んで、読み込んだ項目を格納して比較すればいいのでしょうか? その格納の仕方が分かってないんです; もし宜しければその辺りを教えて下さると助かります!

関連するQ&A