アイテムを分割せずに大容量ファイルをチャンクに分割する

アイテムを分割せずに大容量ファイルをチャンクに分割する

UIEE形式のかなり大きな.msgファイルがあります。

$ wc -l big_db.msg
8726593 big_db.msg

デフォルトでは、ファイルは次のようにさまざまな長さの項目で構成されます。

UR|1
AA|Condon, Richard
TI|Prizzi's Family
CN|Collectable- Good/Good
MT|FICTION
PU|G.P. Putnam & Sons
DP|1986
ED|First Printing.
BD|Hard Cover
NT|0399132104
KE|MAFIA
KE|FICTION
PR|44.9
XA|4
XB|1
XC|BO
XD|S

UR|10
AA|Gariepy, Henry
TI|Portraits of Perseverance
CN|Good/No Jacket
MT|SOLD
PU|Victor Books
DP|1989
BD|Mass Market Paperback
NT|1989 tpb g 100 meditations from the Book of Job "This book...help you
NT| persevere through the struggles of your life..."
KE|Bible
KE|religion
KE|Job
KE|meditations
PR|28.4
XA|4
XB|5
XC|BO
XD|S

これは、空白行で区切られた2つの項目の例です。 1つのアイテムを2つのファイルに分割せずに、この大きなファイルをより小さなファイルに分割したいと思います。

ファイル内の個々の項目は改行文字(完全に空白行)で区切られます。この870万行のファイルを15個のファイルに分割したいと思います。同様のツールがあることを知っていますが、splitファイルを分割する方法はわかりませんが、単一の項目が複数のファイルに分割されないように改行でのみ可能です。

ベストアンサー1

次の提案を使用してくださいcsplit

行番号に分割

$ csplit file.txt <num lines> "{repetitions}"

はい

1000行のファイルがあるとしましょう。

$ seq 1000 > file.txt

$ csplit file.txt 100 "{8}"
288
400
400
400
400
400
400
400
400
405

結果は次のファイルです。

$ wc -l xx*
  99 xx00
 100 xx01
 100 xx02
 100 xx03
 100 xx04
 100 xx05
 100 xx06
 100 xx07
 100 xx08
 101 xx09
   1 xx10
1001 total

特定のファイルの行数に基づいて反復回数を事前に計算して、反復回数を指定する必要がある静的制限を回避できます。

$ lines=100
$ echo $lines 
100

$ rep=$(( ($(wc -l file.txt | cut -d" " -f1) / $lines) -2 ))
$ echo $rep
8

$ csplit file.txt 100 "{$rep}"
288
400
400
400
400
400
400
400
400
405

空行に分割する

一方、ファイルに含まれる空白行にファイルを単純に分割するには、次のバージョンを使用できますsplit

$ csplit file2.txt '/^$/' "{*}"

はい

上記の4行の空行を追加してfile.txtファイルを作成したとしますfile2.txt。以下のように手動で追加されたものが表示されます。

$ grep -A1 -B1 "^$" file2.txt
20

21
--
72

73
--
112

113
--
178

179

上記は、サンプルファイルの対応する数値の間に追加したものを示しています。これでcsplitコマンドを実行すると、次のようになります。

$ csplit file2.txt '/^$/' "{*}"
51
157
134
265
3290

これで、空の行で区切られた4つのファイルがあることがわかります。

$ grep -A1 -B1 '^$' xx0*
xx01:
xx01-21
--
xx02:
xx02-73
--
xx03:
xx03-113
--
xx04:
xx04-179

引用する

おすすめ記事