
お世話になります。
rubyを用いたx行からy行までの抜き出しについて教えて頂きたいです。
現在、
test1.inp
というファイルがあり、そのtest1.inpを
指定列から106577行ずつ切り出したファイルを作りたいと思い、
ruby -e 'puts ARGF.read.split("\n")[211579..318156]' test1.inp > data1.txt
ruby -e 'puts ARGF.read.split("\n")[423162..529739]' test1.inp > data2.txt
ruby -e 'puts ARGF.read.split("\n")[634745..741322]' test1.inp > data3.txt
ruby -e 'puts ARGF.read.split("\n")[846328..952905]' test1.inp > data4.txt
ruby -e 'puts ARGF.read.split("\n")[1057911..1164488]' test1.inp > data5.txt
(以下まだまだ続く。)
というワンライナー構文を書いて切り出しをしております。
どういうことかというと
211580行目から318157行目までをdata1.txtというファイルで書き出せ。(rubyは1行目を0行目とするのでプログラム上での数字は-1行されています。)
423163行目から529739行目までをdata2.txtとして書き出せ。
という構文であります。
上記のように、ワンライナーですと、ファイルを切り出するたびにtest1.inpという親ファイルを閉じてしまうために、test1.inpファイルのサイズが大きい場合には非常に時間がかかってしまうという欠点が出ています。
そこで、test1.inpファイルを毎回毎回開いては閉じてという工程をさせないようにさせる、
つまりdata1.txtやdata2.txtを高速で出力させる方法がわかる方がお見えでしたら是非ともこの方法を教えてください。
よろしくお願いします。

No.1ベストアンサー
- 回答日時:
データがあれば、延々とdata1.txt・・・・dataN.txtを作成し続けます。
以下のスクリプトを実行してください。
ruby スクリプト名 test1.inp のように入力します。
---------------------------------------------------------
# coding:WINDOWS-31J
StartLine = 211580 #出力開始行
Span = 211583 #出力間隔(次の出力開始行までの間隔)
Band = 106577 #出力範囲(出力開始行から何行出力するかの範囲)
ls = StartLine
le = ls + Band
ofp = nil
fno = 1
lno = 0
File.open(ARGV[0]) do |file|
while line = file.gets
lno += 1
#読み込んだ行が開始行~終了行の範囲内なら、以下の処理を行う
if lno >= ls && lno <= le
#開始行の場合、出力ファイルをオープンする
if lno == ls
ofp = File.open("data" + fno.to_s + ".txt","w")
end
#1行出力
ofp.print line
#終了行に達した場合、出力ファイルをクローズし、次の出力に備える
if lno == le
ofp.close
ofp = nil
fno += 1
ls += Span
le = ls + Band
end
end
end
end
#途中で終わった場合、出力ファイルをクローズ
if ofp != nil
ofp.close
end

No.2
- 回答日時:
>puts ARGF.readなどARGFを使う時だけマイナス1しなければならないのでしょうか?
いいえ。今回のあなたが作成されたワンライナーの構文の為です。
ワンライナーで記述された以下のスクリプトは、
ruby -e 'puts ARGF.read.split("\n")[211579..318156]' test1.inp > data1.txt
下記のような処理になります。
1. test1.inpを内部メモリに全て読み込み・・・・ファイルサイズ分のメモリが必要
2. 内部メモリに読み込んだ文字列を\nで分割し、配列に格納・・・・更に、ほぼ同じサイズのメモリが必要
3.上記の配列の文字列[211579]~文字列[318156]を出力
上記の1行目のデータは文字列[0]になります。文字列[211579]とは211580行目のデータです。
マイナス1するのは、1行毎に配列に格納している為です。(配列の添え字は0から始まります)
ARGFをつかっている為ではありません。
尚、実行速度ですが、上記の1と2でおよそファイルサイズ×2のメモリを必要としています。
今回はファイルサイズが大きいため、その影響で、遅くなっていると考えられます。(推測ですが)
ようやく納得できました。
全てメモリに格納してからさらに分割ですメモリ使うという処理を繰り返すとか、とんでもない負荷をPCにかけてたような…(汗
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ruby OpenURI::Meta
-
Ruby require ライブラリー
-
Accessで文字列のバイト数読み込み
-
【メモリ不足で落ちる(python)】
-
1、Rstudioで回帰直線を求める...
-
VBScriptでExcel(2019)上のデー...
-
クリスタルレポートで困ってい...
-
パイソンプログラム
-
7セグメント LED ディスプレイ ...
-
ruby while式
-
ruby loopメソッド 変数(再喝)
-
ruby 配列
-
ruby loopメソッド 変数
-
ruby クラス・オブジェクト・イ...
-
ルビー言語 ライブラリー 追記
-
ruby raise句
-
ruby begin句
-
ruby ensure句
-
ルビー言語 ライブラリー(再々...
-
ルビー言語 csvファイル 続き(...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
初心者 パイソンプログラム
-
;nilの意味
-
rubyでバイナリファイルを直接...
-
小文字wと大文字Wの区別
-
ruby on railsインストールでエ...
-
プログラミング言語で大文字と...
-
COBOLのIFの入れ子について
-
VB.NETで階乗を求めるプログラ...
-
web上のhtmlファイルから文字デ...
-
画像をページ右側に並べる方法...
-
Xcodeでランダム整数
-
RubyでNo such file or directo...
-
Pro*CとCの間|変数の有効範囲
-
プログラミング講師はまだ需要...
-
rubyプログラムからrubyプログ...
-
ruby の File.exist? メソッド...
-
たびたびすいません。VBAです。
-
Ruby / passenger のインストー...
-
GoTo文について
-
Ruby
おすすめ情報
実行してみました。
ものすごく速いですね。いままでのワンライナー構文の100倍以上の速度出ます。
rubyでは開始行数、StartLine = 211580 #出力開始行
のところをマイナス1行して211579にしてやらなければならないと思っていたのですが、マイナス1しなくても良いのですね。puts ARGF.readなどARGFを使う時だけマイナス1しなければならないのでしょうか?