rubyで複数列のデータを1行に列ごとにつなげるコードを知りたいです
- 評価
- クリップ 1
- VIEW 1,948
rubyを用いたプログラムで、複数列のデータを1行にまとめる方法を知りたいです。
rubyというプログラムの勉強中です。
テキストファイルの出力に関してなのですが、質問させてください。以下の様なデータがあり、一列当たりはスペース含め40文字で区切られているprnファイルであります。
それを縦方向に積み重ねていくというプログラムを組もうとしました。以下がその例です。
1,2,1, 2,2,1, 3,2,1,
X方向_変位0.01 X方向_変位0.02 X方向_変位0.03
0,0,0, 0,0,0, 0,0,0,
2,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
1,2,2,7, 1,2,2,7, 1,2,2,7,
0,1,1, 0,1,1, 0,1,1,
1,data1, 1,data2, 1,data3,
2,data1, 2,data2, 2,data3,
3,data1, 3,data2, 3,data3,
4,data1, 4,data2, 4,data3,
5,data1, 5,data2, 5,data3,
6,data1, 6,data2, 6,data3,
7,data1, 7,data2, 7,data3,
8,data1, 8,data2, 8,data3,
9,data1, 9,data2, 9,data3,
10,data1, 10,data2, 10,data3,
11,data1, 11,data2, 11,data3,
12,data1, 12,data2, 12,data3,
13,data1, 13,data2, 13,data3,
14,data1, 14,data2, 14,data3,
15,data1, 15,data2, 15,data3,
-1,0, -1,0, -1,0,
であります。(スペース区切りの前にカンマがありますが、これは区切り文字ではなく、あくまでスペースで区切られております) 列の長さは不定であり、データ列間は半角スペースのみで区切られております。
上記のようなデータを
1,2,1,
X方向_変位0.01
0,0,0,
2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
1,2,2,7,
0,1,1,
1,data1,
2,data1,
3,data1,
4,data1,
5,data1,
6,data1,
7,data1,
8,data1,
9,data1,
10,data1,
11,data1,
12,data1,
13,data1,
14,data1,
15,data1,
-1,0,
2,2,1,
X方向_変位0.02
0,0,0,
2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
1,2,2,7,
0,1,1,
1,data2,
2,data2,
3,data2,
4,data2,
5,data2,
6,data2,
7,data2,
8,data2,
9,data2,
10,data2,
11,data2,
12,data2,
13,data2,
14,data2,
15,data2,
-1,0,
3,2,1,
X方向_変位0.03
0,0,0,
2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
1,2,2,7,
0,1,1,
1,data3,
2,data3,
3,data3,
4,data3,
5,data3,
6,data3,
7,data3,
8,data3,
9,data3,
10,data3,
11,data3,
12,data3,
13,data3,
14,data3,
15,data3,
-1,0,
4,2,1,
X方向_変位0.04
0,0,0,
2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
1,2,2,7,
0,1,1,
1,data4,
2,data4,
3,data4,
4,data4,
5,data4,
6,data4,
7,data4,
8,data4,
9,data4,
10,data4,
11,data4,
12,data4,
13,data4,
14,data4,
15,data4,
-1,0,
以下続く
と重ねたいという意味です。
自分で組んだところ、一列目のみが出力されて、二列目三列目のデータが出力されませんでした。
二列目以降がうまく取得できていないのですが、サンプルというよりはこのように組めば大丈夫というプログラムの答えが知りたいです。なお、本当のファイルは横に多いと1000列で1万行近くになります。そのため、私が一番得意なVBAでは作業ができず困っております。巨大なファイルが操れるrubyやphysonならできるのではないかと思っての質問です。
。
この完成したファイルをファイル②とすると、その前にファイル①を加え、ファイル②の後ろにファイル③を付け加えたファイル完成版というのを作ることも可能なのでしょうか?というのも、とてつもなくファイルが大きくなってテキストエディタではファイル②を編集することも困難になりそうだからです。
よろしくお願いします。
修正追記
ご指摘を受けましては、2行目の部分に余分なスペースが入っていたのを修正いたしました。このデータは一列あたり 半角39文字+区切り用半角スペース1文字の40カラム型であり、半角39文字に足りていない箇所には39文字となるように強制的に半角スペースが挿入される仕様になっております。その上で区切り半角スペース1文字追加で40カラムとなります。
追記事項としまして、このデータは数値解析結果なのですが、スペース区切りではなく、一列あたり半角40文字でタブ区切りという形も出力出来るようなのですが、rubyではスペース区切りとタブ区切りのどちらの方が操りやすいでしょうか?(40文字の半角+tab区切り)
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
2行目だけ除外して考えると、全行が3要素なので、配列に読み込んでtranspose(転置行列)でいいです。
puts ARGF.map{|line| line.chomp.split(/ /)}.transpose
2行目だけ特別扱いするとなると、6要素を2つずつ組にしてくっつけます。
puts ARGF.map{|line|
if /X方向_変位/ =~ line
line.chomp.split(/ /).each_slice(2).map{|x| x.join(" ")}
else
line.chomp.split(/ /)
end
}.transpose
メモリに入りきらないくらいのファイルサイズだとすると、ファイルを3回読むと言うことになりますね。
質問コメントを見ての追記
改行で区切られており、末尾に空白が詰まっていると言うことであれば、最初のプログラムの改善で、
puts ARGF.map{|line| line.rstrip.split(/ /)}.transpose
コマンドラインから、
ruby -e "puts ARGF.map{|line| line.rstrip.split(/ /)}.transpose" 入力ファイル > 出力ファイル
で。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
0
変換結果をファイルに保存するようにしてみました。
さらに、変換結果(out.txt) を元のファイル形式(out2.txt) に戻す処理も書き、それが最初のデータ内容(data.txt) とも一致することを確認しました。
r.rb
require 'csv'
in_file = 'data.txt'
out_file = 'out.txt'
out_file2 = 'out2.txt'
SEP = ' '.freeze
arrs = CSV.table(in_file, col_sep: SEP, headers: %w(1 2 3))
CSV.open(out_file, 'wb', col_sep: SEP) do |csv|
arrs.by_col!.headers.each do |col|
arrs[col].each { |item| csv << [item] }
end
end
items = File.readlines(out_file).map(&:chomp)
CSV.open(out_file2, 'wb', col_sep: SEP) do |csv|
num = items.size
base1 = num / 3
base2 = base1 * 2
(0...(num / 3)).each do |i|
csv << [items[i], items[base1 + i], items[base2 + i]]
end
end
実行例
$ cat data.txt
1,2,1, 2,2,1, 3,2,1,
X方向_変位0.01 X方向_変位0.02 X方向_変位0.03
0,0,0, 0,0,0, 0,0,0,
2,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
1,2,2,7, 1,2,2,7, 1,2,2,7,
0,1,1, 0,1,1, 0,1,1,
1,data1, 1,data2, 1,data3,
2,data1, 2,data2, 2,data3,
3,data1, 3,data2, 3,data3,
4,data1, 4,data2, 4,data3,
5,data1, 5,data2, 5,data3,
6,data1, 6,data2, 6,data3,
7,data1, 7,data2, 7,data3,
8,data1, 8,data2, 8,data3,
9,data1, 9,data2, 9,data3,
10,data1, 10,data2, 10,data3,
11,data1, 11,data2, 11,data3,
12,data1, 12,data2, 12,data3,
13,data1, 13,data2, 13,data3,
14,data1, 14,data2, 14,data3,
15,data1, 15,data2, 15,data3,
-1,0, -1,0, -1,0,
$ ls *.txt
data.txt
$ ruby r.rb
$ ls *.txt
data.txt out.txt out2.txt
$ cat out.txt
1,2,1,
X方向_変位0.01
0,0,0,
2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
1,2,2,7,
0,1,1,
1,data1,
2,data1,
3,data1,
4,data1,
5,data1,
6,data1,
7,data1,
8,data1,
9,data1,
10,data1,
11,data1,
12,data1,
13,data1,
14,data1,
15,data1,
-1,0,
2,2,1,
X方向_変位0.02
0,0,0,
2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
1,2,2,7,
0,1,1,
1,data2,
2,data2,
3,data2,
4,data2,
5,data2,
6,data2,
7,data2,
8,data2,
9,data2,
10,data2,
11,data2,
12,data2,
13,data2,
14,data2,
15,data2,
-1,0,
3,2,1,
X方向_変位0.03
0,0,0,
2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,
1,2,2,7,
0,1,1,
1,data3,
2,data3,
3,data3,
4,data3,
5,data3,
6,data3,
7,data3,
8,data3,
9,data3,
10,data3,
11,data3,
12,data3,
13,data3,
14,data3,
15,data3,
-1,0,
$ diff data.txt out2.txt
$ cat out2.txt
1,2,1, 2,2,1, 3,2,1,
X方向_変位0.01 X方向_変位0.02 X方向_変位0.03
0,0,0, 0,0,0, 0,0,0,
2,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,
1,2,2,7, 1,2,2,7, 1,2,2,7,
0,1,1, 0,1,1, 0,1,1,
1,data1, 1,data2, 1,data3,
2,data1, 2,data2, 2,data3,
3,data1, 3,data2, 3,data3,
4,data1, 4,data2, 4,data3,
5,data1, 5,data2, 5,data3,
6,data1, 6,data2, 6,data3,
7,data1, 7,data2, 7,data3,
8,data1, 8,data2, 8,data3,
9,data1, 9,data2, 9,data3,
10,data1, 10,data2, 10,data3,
11,data1, 11,data2, 11,data3,
12,data1, 12,data2, 12,data3,
13,data1, 13,data2, 13,data3,
14,data1, 14,data2, 14,data3,
15,data1, 15,data2, 15,data3,
-1,0, -1,0, -1,0,
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
otn
2017/01/14 22:57
2行目が、空白区切りだと6列になりますが、この行だけ特別扱いですか?
sakuya_izayoi
2017/01/14 23:23
いえ、掲示板に貼り付けた都合上スペースがおかしくなっているのですが、実際のファイルは一列当たりは39文字+半角スペース1文字の40カラムであります。
otn
2017/01/14 23:30
ではちゃんと貼り付けてください。
otn
2017/01/15 00:03
改行で区切られた行じゃなくて、改行無しの1レコード40文字の固定長レコードファイルと言うことですか?
otn
2017/01/15 00:06
あと、「自分で組んだところ、」というプログラムも載せた方が良いですね。
sakuya_izayoi
2017/01/15 01:26 編集
固定長のレコードでございます。あと、文面からではrubyで組んだと誤認させることとなっており申し訳ありません。これはvbaで組んだものであります。rubyなら出来るのでは無いかと思った理由も解析プログラムがrubyで動いているのが分かったからであります。自分ではrubyのじゃんけんゲーム程度しかまだ組めず、ファイル操作を今学習している所であり、答えから分解して学習しているところでもあります。
otn
2017/01/15 08:44
固定長というのは良いのですが、行の区切りの改行は存在するのですか?
sakuya_izayoi
2017/01/15 10:09
おはようございます。行区切りの改行はワードなどでいうEnterキーでできる「改行」マークになっております。(Shift]+[Enter]で改行すると「↓」の改行マークではない) です。よろしくお願いします。