重複した単語を削除する方法

このQ&Aのポイント
  • grep関数を使用して、複数行からの抽出を行います。
  • 同じ行で重複した単語を削除するために、ハッシュを使用します。
  • ファイルの各行に対して、重複した単語を削除して出力することで、目的の結果を得ることができます。
回答を見る
  • ベストアンサー

grep関数を用いた複数行からの抽出

同じ行で重複した単語を削除したいです。 テキストファイル sapporo aomori akita iwate akita yamagata sendai miyagi hukushima miyagi akita mito ・ ・ 上記のようなファイルの同じ行で重複した単語を削除し下の形にしたいです。 sapporo aomori akita iwate yamagata sendai miyagi hukushima akita mito ・ ・ open(FILE1, "<xxx.txt") || die "File1 Open Error! \n"; open(OUT, ">zzz.txt") || die "OUT Open Error! \n"; $string1 = <FILE1>; my @array = split(/\t/,"$string1"); my %count; @array = grep {!$count{$_}++}@array; foreach my $element (@array) { print OUT "$element\t"; } close(FILE1); close(OUT); このプログラムを実行すれば初めの一行は重複した単語を削除できるのですがそこで終了してしまいます。2行目、3行目・・といったように複数行に対して重複した単語を削除するためにはどのようにすればいいのですか。宜しくお願いします。

  • Perl
  • 回答数2
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • taco0603
  • ベストアンサー率63% (21/33)
回答No.2

>$string1 = <FILE1>; これは配列で受け取ってないので、入力ファイルから1行だけ取得する処理です。 なので全行を読み込むのであれば、No.1さんの言うとおり、ループさせる必要があります。 ループの書き方ですがファイルハンドルをwhileでループさせるか、一度配列に落としてforeachでループさせるかがベタではないかと。配列に落とすんならこんな感じですかね…。 --- my @data = <FILE1>; chomp @data; foreach my $line (@data) { my @array = split(/\t/, $line); my %count; @array = grep {!$count{$_}++}@array; foreach my $element (@array) { print OUT "$element\t"; } print OUT "\n"; } --- 改行を削除しないと整形したファイルの先頭に\tがつくんで、とりあえずchompして、レコードの最後に改行付けてます。

nanashim
質問者

お礼

splitで文字列を分割してリストにした後、どのようにループさせれば 良いかを考えてしまい、悪戦苦闘していました(> <) chompの使い方含め、大変勉強になりました。有難うございました。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

ループする

関連するQ&A

  • Perlを使って、大文字小文字関係なく、重複行を削除したい。

    現在、下記のコードで重複行を削除し、ファイルを作成しているのですが、 AAA aaa AaA などのように大文字、小文字が混じっている場合は重複とはみなさず削除の対象になりません。 こういった場合も重複とみなして削除させたいのですがどのようにすればいいでしょうか? open(IN, "INfilename.txt"); open(OUT, ">Outfilename.txt"); while(){ if(!exists($count{$_})){$count{$_}++;print OUT $_;} } close (IN); close (OUT);

    • ベストアンサー
    • CGI
  • Perlで重複行を削除したい

    あ b c d e e g あ b c d e e g い b c d e e g い c c d e e g 上記のようなCSVデータ(タブ区切り)が100行くらいあるのですが、1列目にある、あ、あ、い、いは無視して、2列目以降のデータのみで重複を比較して同じ行は削除したいのですがどのようにすればよいでしょうか? 下記コードを応用すれば分かりそうなのですが、自分で作ることができませんでした。 どなたか、教えていただけ無いでしょうか? 宜しくお願い致します。 open(OUT, "$file"); @array = <OUT>; close(OUT); my %count; @array = grep(!$count{$_}++, @array); print @array;

    • ベストアンサー
    • CGI
  • Perlで空白行を削除

    現在、Perlにて外部のcsvファイルを読み込み、"重複行"と"空白行"を削除するプログラムを作成しています。 重複行を削除する部分は ------ open(IN, "csvtime.csv"); @data = <IN>; close(IN); @data = grep {!$count{$_}++} @data; open(OUT, "> csvtime.csv"); print(OUT @data); close(OUT); ------ でできたのですが、空白行を削除する部分がわかりません。 申し訳ないのですが、お教えいただけないでしょうか。 また、空白行で最初の空白行は残すようにしたいです。 よろしくお願いいたします。 例) 読み出しデータ ----- (ヘッダ1行目) (ヘッダ2行目) (ヘッダ3行目) (必要な空白) (ヘッダ4行目) 00:00:00,302 00:01:00,274 00:02:00,272 00:03:00,248 00:04:00,237 00:05:00,239 00:05:00,239 00:06:00,256 00:07:00,260 00:08:00,250 00:09:00,253 00:10:00,241 ----- 加工後データ ----- (ヘッダ1行目) (ヘッダ2行目) (ヘッダ3行目) (必要な空白) (ヘッダ4行目) 00:00:00,302 00:01:00,274 00:02:00,272 00:03:00,248 00:04:00,237 00:05:00,239 00:06:00,256 00:07:00,260 00:08:00,250 00:09:00,253 00:10:00,241 -----

    • ベストアンサー
    • Perl
  • perlCGIが動かなくないました。改良していただけないでしょうか?

    下記のようなperl-cgiをプロバイダのサーバで使っていたのですが、最近、動かなくなりました。 多分、読み込むファイルの大きさが大きすぎて、途中で止まっているのではないかと思います。 (試しに、10M程度のファイルで行うと、問題なく動きました) 因みに、現在のサイズは、50MBくらいです。 これからも、肥大の一途とたどるのですが、なるべく、サーバに負担をかけず同じファイルを作成できないものでしょうか? とても、困っています。 どなたか、改良できる方、何卒、宜しくお願い致します。 #下記は、INfilenemeから、重複する行を削除して、Outfilenameというファイルを作るperlコードです。 open(IN, "INfilename.txt"); @array = <IN>; close (IN); %count; @array = grep(!$count{$_}++, @array); open(OUT, ">Outfilename.txt"); print OUT join("",@array); close (OUT);

    • ベストアンサー
    • CGI
  • マッチした行の上の行を抽出

    初心者で至らぬ点が多々有りますが、宜しくお願いします。 環境はWindows7-64bit、ActivePerl 5.12.4 Build(64bit)を使用しています。 テキストが数百個有り、全て以下のような構成になっています。 文章1 文章2 文章3 kwd 文章4 kwd 文章5 文章6 kwd    ~以下略~ ファイル郡をリストとして読み込み、それぞれのファイルに対して kwdをキーとして検索し、該当した行の上の行を抽出しようとしています。 ~ファイルリスト読み込みルーチンは省略、以下各ファイル毎のサブルーチン~ sub execute { open(INP, "$inp"); #ファイル読み込み open(OUT, ">rep\\$inp"); #ファイル書き出し(フォルダを変えて同名) while(<IN>){ if($_ =~ m/kwd/){ #現在の行が"kwd"を含んでいたら print OUT $prev; #前の行を抽出のつもり } $prev = $_; #現在の行データを$prevに格納 } close(INP); close(OUT); } $_には現在の行データが入っていると認識しており 上記の書き方で$prevには一段上の行データが入るのでは と思ったのですが、現状$prevを出力してもカラです。 文法ミスよりも、そもそも考え方が間違っているような気がして なりませんが、どうか解決法を教えて頂きたく。

  • perlでcsvファイルから複数行を抽出したい

    プログラミング初心者です。 お知恵をお貸しください。 perlでcsvファイルから任意の複数行を、コマンドライン引数を使って抜き出したいです。 1行だけだとうまくいきますが、以下ではすべてのcsvデータが出力されてしまいます。 ----------------------getcsv.pl ここから---------------------- #!/usr/bin/perl -- use strict; use warnings; open(IN, "<adata.csv"); open (OUT, ">$bdata.csv"); while(<IN>){ if($. == $ARGV[0] || $ARGV[1] || $ARGV[2] || $ARGV[3]) { print OUT $_; } } close(IN); close (OUT); ----------------------getcsv.pl ここまで---------------------- ----------------------コマンド ここから---------------------- perl getcsv.pl 1 3 8 10 ----------------------コマンド ここまで---------------------- よろしくお願いします。

    • ベストアンサー
    • Perl
  • <IN>のx行目を操作したい

    open(IN, $FILE);した時に、 <IN>のx行目とn行目だけを取り出したいと思っています。 これまでは@array=<IN>;としてきたのですが ファイルが大きくなると非常に遅くなってしまいます。 @arrayに<IN>を格納することなく処理をする事は出来るのでしょうか。 よい方法がありましたら教えて下さい。

    • ベストアンサー
    • Perl
  • EXCEL VBAの重複行削除について

    EXCEL2010を使用しています。 添付画像の「重複行削除 前」の表を、RemoveDuplicatesで下の様にコードを組んで A列で重複する行を見て重複する行を削除しています。 Public Sub 重複行削除()  With WorkSheets(1)   .Range(.Cells(1, 1), .Cells(8, 3)).RemoveDuplicates _      Columns:=1, Header:=xlYes  End With End Sub すると、日付の新しいデータが削除され、古いデータが残ってしまいます。 (添付画像の「重複行削除 後」) ReniveDuplicates Columns:=Array(1,3) とした場合は、すべてのデータが残ってしまいます。 添付画像の「欲しいデータ」の表の様に、 日付の新しいものを残すように重複行削除は出来ないでしょうか? 詳しい方、どうか教えてください。 よろしくお願いします。

  • csvファイルの1カラム目に重複行があればその行全体を削除するには?

    次のようなファイルがあった場合、 1, 2, 3 1, 3, 5 2, 4, 7 3, 1, 0 3, 1, 2 3, 7, 1 4, 0, 0 5, 0, 0 1カラム目が重複する行を検索して、該当する行全体を削除し、(最初に見つかった行はそのままで、それ以降の重複行は削除したい)次のようなファイルにする場合は、どのようなコマンド、スクリプト作成すればよいでしょうか? 1, 2, 3 2, 4, 7 3, 1, 0 4, 0, 0 5, 0, 0

  • 秀丸エディターでのGREP検索で

    秀丸でGREP検索をすると、 ファイル名 (行行番号) 単語 という形式で出力されますが、ファイル名 (行行番号) の部分が余分です。もちろん、後で置き換えして削除することはできますが、最初からファイル名 (行行番号) を出力させないようにするにはどうすればいいのでしょうか?

専門家に質問してみよう