csv(tsv?)内の複数行のデータを1行にまとめる方法とは?

このQ&Aのポイント
  • 正規表現とperlを一週間くらい前から勉強し始めた超初心者です。htmlとcssを多少知っているレベルの人間です。
  • miというmacのテキストエディタにcsvのデータを貼付けてやっているのでたぶんタブ区切りのカタチでやっていることになるのではないかと思っています。
  • そこで、(.*?) (.*?) (.*?) (.*?)を使って3行ごとにヒットさせた結果を並べ替えようとしていますが、うまくいっていません。焦っています。
回答を見る
  • ベストアンサー

置換でcsv(tsv?)内の複数行のデータを1行にまとめたい。(超初心

置換でcsv(tsv?)内の複数行のデータを1行にまとめたい。(超初心者です) 正規表現とperlを一週間くらい前から勉強し始めた超初心者です。htmlとcssを多少知っているレベルの人間です。 AAA,1,2,2 データイ,3,-1,0 データロ,1,0.25,8 BBB,1,2,2 データイ,3,-1,0 データロ,1,0.25,8 CCC,1,2,2 データイ,3,-1,0 データロ,1,0.25,8 のような3行一組のデータを AAA,1,2,2,3,-1,0,1,0.25,8 BBB,1,2,2,3,-1,0,1,0.25,8 CCC,1,2,2,3,-1,0,1,0.25,8 のように一番上の行にまとめようとしています。 miというmacのテキストエディタにcsvのデータを貼付けてやっているのでたぶんタブ区切りのカタチでやっていることになるのではないかと思っています。 いろんなサイトの見よう見真似でやった結果、 (.*?)\t(.*?)\t(.*?)\t(.*?) データイ\t([-]??d+(?.?d+)?)\t([-]??d+(?.?d+)?)\t[-]??d+(?.?d+)? データロ\t([-]??d+(?.?d+)?)\t([-]??d+(?.?d+)?)\t[-]??d+(?.?d+)? で3行ごとにヒットはするようになりましたが、並べ替えの仕方がよくわかりません。 [-]??d+(?.?d+)? をそれぞれ( )で囲んで $1\t$2\t$3\t$4\t$5\t$6\t$7\t$8\t$9\t$10\t$12 のようにやってみましたが、$6あたりから後がでてきませんでした。 たぶんかなりとんちんかんなことをやっている気がしているのですが、20000行近いデータの集計を早急に出さなければならない状況に置かれており焦っています。 よろしくお願いします。

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

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

  • ベストアンサー
回答No.2

データの並びが保証されているのならば データ全体の中から改行+データイ|データロを削除すればいいのでは? s/\r?\n?(?:データイ|データロ)//g;とか。。。 こんなことならテキストエディタの方が楽の予感? あとは、地道に1行読んで1列目を削除して結合とかで十分だとおもいますよ。 @A1 = split(/,/, <>); @A2 = split(/,/, <>); shift @A2; @A3 = split(/,/, <>); shift @A3; print join(",", @A1, @A2, @A3) . "\n" とか

umuquzi
質問者

お礼

2、3行目の改行と1列目の文字を削除すればいいんですね。 確かに。。。 全然思いつきませんでした。 スキルアップがんばります。 ありがとうございました。

その他の回答 (1)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

csvと、miに貼り付けたからTSV、との関係がよくわからないのですが。 1行目はすべて 2,3行目は先頭1項目以外 を横につなげる、ということでよろしいですか? 並び変えよう、などと考えず、 ・1行目、2行目の改行を削除 ・2行目、3行目の第1項目を削除 と考えればよいのです。 例えば #!/usr/bin/perl #↑実際のに合わせる $l = 0 ; #現在の行数-1 while(<>) { s/[\r\n]*$// ; # 改行文字を削除。CR,LF,CRLFに対応 #if ( ! /,/ ) { next;} #余計な行の削除例:カンマの無い行はとばす #if( ( $l == 0 ) && ! /^([^,]*,){3}[^,]*$/ )) { #next; #} #余計な行の削除例: データ開始行まで行数をカウントしない if ( $l == 0 ) { # 1行目 →そのまま print ; } else { s/^[^,]*,/,/ ;#先頭2項目削除 print ; #3行目なら改行 if ( $l == 2 ) { print "\n"} } $l ++ ; if ( $l > 2 ) { $l = 0 ; } # 3行目では0のもどす }

umuquzi
質問者

お礼

完全に並べ替えに心が奪われていました。 この方法だと一気にできてよさそうですね。 丁寧なコメントもありがとうございます! 未来のために試してみます。

関連するQ&A

  • 大量のCSVデータを1つのエクセルデータにまとめる方法について

    今仕事で、CSVファイルが400ファイル程あり、これを一つの エクセルファイルにまとめなくて加工しなければならないのですが うまいことVBAを活用して効率的にできないか思案中なのですが うまい具合に行きません。 データの持ち方として ○CSVファイル1 1.AAA 2.BBB ○CSVファイル2 3.CCC 4.DDD となっており、これを1つのエクセルファイル上で 1.AAA 2.BBB 3.CCC 4.DDD としたいのですがなにかいい方法はないでしょうか? 1つのブックで外部データの取り込みでCSVを次々に選択して いくVBAなんてあれば教えていただけないでしょうか? よろしくお願いします。

  • SpreadのデータをCSVに出力する際。。。

    いつもお世話になっております。 現在SpreadのデータをCSVに出力するプログラムを作成しています。 例えば、Spreadのデータに… ------------------- AAA BBB CCC DDD BBB DDD ------------------- というデータが入っている場合、 CSVには… ------------------- AAA BBB CCC DDD ------------------- という風に出力したい(重複した場合は一方だけ出力)のですが、 なかなかうまくいきません(汗) どのようなプログラムを組めばうまくいくか、 ご教授して頂ければ幸いです。 宜しくお願いします。 ※そのままCSVに出力するやり方はわかります。

  • csvデータの置換について

    お世話になります。 batファイルを利用してcsvファイルの数値の置換をしたのですが、ご教授下さい。 詳細は下記になります。 【環境】 Windows2008 Server 【対象ファイル】 test.csv 【実施内容】 ファイルの内容は下記になります。 A,111,aaa B,222,bbb C,333,ccc D,444,ddd E,555,eee 上記の内容で数値を下記のように置換したい。 111は111F 222は222G 333は333H 444は444I 555は555J よろしくお願い致します。

  • EXCELで行の先頭データが同じ行の削除方法について

    EXCELで次のようなことをしたいのですがどうしたら簡単にできるでしょうか?  AAA   AAA  AAA  AAA  AAA  BBB  BBB  BBB  CCC  DDD  DDD  DDD  DDD 上ようのなデータで重複している部分を削除し、  AAA  BBB  CCC  DDD としたいのですが。 今は一行々々で確認しながら削除してます。3000行程あり困ってます。 どうしたら簡単にできるでしょうか?  

  • 複数行書き込むにはどうしたら良いのでしょうか?

    <?php exec("sh -c 'echo \"aaa\" > write.txt'", $result); ?> で、ファイルにaaaと書き込めるようですが、 このようなシェルをexec、system関数から実行する方法で、aaaではなく、 aaa bbb ccc と複数行のデーターをファイルに書き込みたい場合は、どのようにしたら良いのでしょうか?

    • ベストアンサー
    • PHP
  • 該当項目表示についての追加質問

    csvデータの列に%で区切った項目があります。 例) 1行目:aaa%bbb%ccc 2行目:aaa&bbb%ddd 3行目:aaa%bbb csvデータ内にはaaaは3個だけですが下記コードで実行すると aaaが6個と計算されます。bbb、ccc、dddの個数は正確に計算されます。 $find = 0; for($d = 0 ; $d < @TEST ; ++$d) { (@ITEM) = split(/\,/, $TEST[$d]); @T = split(/\%/, @ITEMD[2]); #csvデータ内項目%区切り if($in{'item'} eq @T[0]) #@T[0]にaaaが入ります { if(($in{'item2'} eq "") or ($in{'item2'} eq "全て")) { @FIND[$find] = $TEST[$d]; $find++; } elsif($in{'item2'} eq @T[2]) { @FIND[$find] = $TEST[$d]; $find++; } if($in{'item2'} eq @T[1]) { if(($in{'item3'} eq "") or ($in{'item3'} eq "全て")) { @FIND[$find] = $TEST[$d]; $find++; } elsif($in{'item3'} eq @T[2]) { @FIND[$find] = $TEST[$d]; $find++;     }    }   } } ご教授お願いいたします。

    • ベストアンサー
    • Perl
  • CSVデータをツリー表示させたい

    業務で、WEBサイトにCSVデータを表示させたいと考えています。 CSVデータは、毎日更新されるもので、行数も日々変更されます。 項目の中に「レベル」という項目があり、この「レベル」の値を使って、 ツリー表示出来ないかと考えています。 希望としては、決められたフォルダに決められたファイル名で、 CSVデータを置けば、自動的にWEB上にツリー表示されるという ことです。 J-query等で、これを実現出来るプラグインが無いか探しているのですが、 なかなか希望に合うものが見つからず、困っています。 (CSVをWEB表示するものは見つかるのですが、ツリー表示出来る ものが見つかりません) 何か、良い方法があれば、ご教示頂けませんでしょうか? 例 コード  レベル 品名  規格 ・・・・    コード     レベル 品名  規格 ・・・・  1234    1   AAA   aaa       -1234       1    AAA   aaa 2345    2   BBB   bbb        ∟2345     2    BBB  bbb 3456    3   CCC   ccc          ∟3456   3    CCC  ccc 4567    3   DDD   ddd          ∟4567   3    DDD  ddd 5678    3   EEE   eee           ∟5678   3    EEE  eee 6789    4   FFF   fff             ∟6789  4    FFF   fff 7890    3   GGG  ggg           ∟7890   3    GGG  ggg

  • テキストデータに書いてある文字(行)をシャッフルしたい秀丸エディタなど

    テキストデータにある文字をシャッフルする方法はありますか? 例えば、 aaa bbb ccc ddd eee を eee bbb aaa ddd ccc のような感じでもともと順番にあった行を変えてシャッフルみたいな感じに したいです。 秀丸エディタやさくらエディタでこのようなことは出来ますでしょうか?

  • エクセルで1行にまとめられたCSVデータを複数行

    エクセルを使ってCSVファイルのデータを参照して複数行にまたがる表に反映させたいのですがうまくいきません。   A B C D E  1 あ い う え お 2 か き く け こ 上記のように1行で1件分のデータがCSVであります。 このデータを   A  B  C  D  E 1 あ う お 2 い え  3 か く こ 4 き け 上記のように参照させたいのです。 数件ならば1件1件を参照させれば表は完成するのですが、数千件あるのでできません。 1パターン作って、あとは連続フィルで出来れば助かります。 説明が難しく、わかりづらいかと思いますがお力をお貸しください。 よろしくお願いいたします。

  • powershellでcsvの集計

    powershellでのcsvデータの集計をしたいのですが、 よくわからず困っています。 csvのデータは、 aaa1,10,10,20 bbb1,100,100,200 aaa1,5,5,6 ccc1,50,50,60 … となっており、キーとなる項目が同じものは、数値を集計して 再度csvにするというものです。(aaa1が同じなので集計) aaa1,15,15,26   bbb1,100,100,200 ccc1,50,50,60 … という感じです。 よろしくお願いします。

専門家に質問してみよう