1

解析するテキスト ファイルがあります。このファイルでは、各レコードのコンテンツが可変行数にまたがっています。レコードあたりの行数は固定数ではありません。ファイルの内容は次のようになります。

ID\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
ID\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
ID\tcontent\tcontent
\tcontent\tcontent

最初のタブ列にレコードがある場所でスライスしたい (ID 列は次の行で空であるため、この方法で新しいレコードを決定する必要があります)。

それを5行のチャンクに分割してからマージするための私の現在のコード:

f = File.read(file).each_line
f.each_slice(5) do | slice_to_handle |
  merged_row = slice_to_handle.delete("\n").split("\t").collect(&:strip)
  # Dealing with the data here..
end

最初の列に ID が設定されたらすぐにスライスするようにこれを変更する必要があります。

4

2 に答える 2

0

Ruby の Array は Enumerable を継承しています。Enumerable にslice_beforeは、あなたの友人である があります。

text_file = "ID\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
ID\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
\tcontent\tcontent
ID\tcontent\tcontent
\tcontent\tcontent".split("\n")

text_file.slice_before(/^ID/).map(&:join) 

次のようになります。

[
  "ID\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent",
  "ID\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent\tcontent",
  "ID\tcontent\tcontent\tcontent\tcontent"
]

text_fileを使用してファイルを丸呑みした場合に得られるものと同様の行の配列ですreadlines

slice_before配列を反復処理してパターンに一致するものを探し、/^ID/見つかるたびに新しいサブ配列を作成します。

map(&:join)サブ配列をウォークスルーし、それらの内容を 1 つの文字列に結合します。

ただし、これはあまりスケーラブルではありません。それを使用すると、ファイル全体をメモリに丸呑みできることに依存することになります。これにより、マシンがトラックで停止する可能性があります。代わりに、コンテンツを 1 行ずつ読み、ブロックを壊してできるだけ早く処理することをお勧めします。

于 2013-07-09T16:15:14.610 に答える