質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

Q&A

解決済

3回答

2922閲覧

[テキスト処理] grepで巨大なサイズのファイルを操作すると強制終了してしまう

aufheben

総合スコア24

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

0グッド

1クリップ

投稿2022/02/20 12:13

https://teratail.com/questions/kvbnxs63kpei19

この質問の操作をしています。この質問のfile1にあたるファイルの行数が5万行で、file2にあたるファイルの行数が28万行でデータの中身も大きいです。(580MB)

この状況で操作した際に、ベストアンサーの

bash

1grep -E -f <(sed -E 's/^([0-9]+).*/^\1[ \t]/' file1) file2

のコマンドを使用すると、強制終了と出てきてしまいます。
おそらくファイルサイズが大きすぎるので、5万行と28万行のマッチングをしているときにメモリが足りなくなってしまうんだと思います。
そう思って、とりあえず28万の方を1万行と1000行に分割してそれぞれforループで同様にやってみましたが、それでも多くて強制終了してしまいました。(1万x5万のマッチングを28回、1000x5万のマッチングを280回)

file1の方も分割してみようと思ったのですが、両方分割した際にすべてのマッチングができているか、どうやってマージするか等いろいろ考慮することが多くて混乱してしまいます。

良い方法がありましたらご教授お願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

適当にデータを作成して使用メモリ量を計測してみました。実行環境は以下の通りで、メモリ使用量(RSS)は最大で 400 MB 程度になりました。

bash

1$ grep -E '^model name' /proc/cpuinfo | uniq 2model name : Intel(R) Core(TM) i5-8500T CPU @ 2.10GHz 3$ uname -isr 4Linux 5.15.0-18-generic x86_64 5$ lsb_release -dr 6Description: Ubuntu Jammy Jellyfish (development branch) 7Release: 22.04 8$ grep --version 9grep (GNU grep) 3.7 10 11# create file1 12$ seq -f '%010g' 1 50000 > file1 13$ wc -l file1 1450000 file1 15$ ls -1sh file1 16540K file1 17 18# create file2 19$ paste <(seq -f '%010g' 1 280000 | shuf) <(base64 -w 2000 /dev/urandom | head -n 280000) > file2 20$ wc -l file2 21280000 file2 22$ ls -1sh file2 23538M file2 24 25# search 26$ /usr/bin/time -v grep -E -f <(sed -E 's/^([0-9]+).*/^\1[ \t]/' file1) file2 > /dev/null 27 Command being timed: "grep -E -f /dev/fd/63 file2" 28 User time (seconds): 9.62 29 System time (seconds): 0.16 30 Percent of CPU this job got: 98% 31 Elapsed (wall clock) time (h:mm:ss or m:ss): 0:09.89 32 : 33 34 Maximum resident set size (kbytes): 408544 35 : 36 37 Exit status: 0

また、file1 のサイズが大きくなる(行数は同じで数値の桁数を増やす)と消費メモリ量がどうなるのかは以下の通りです。

bash

1$ wc -l file1 250000 file1 3$ ls -1sh file1 42.5M file1 5 6Maximum resident set size (kbytes): 1404876 # 1.34 GB 7 8$ wc -l file1 950000 file1 10$ ls -1sh file1 1110M file1 12 13Maximum resident set size (kbytes): 5404804 # 5.15 GB

投稿2022/02/20 14:59

編集2022/02/20 18:40
melian

総合スコア19803

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ファイルの内容に依りますが、

sh

1grep -F -w -f file1 file2

ではどうですか?

あるいは、例示のようにファイルが第一列でソートされているのなら、

sh

1join -j 1 file1 file2

で。
これはメモリをほとんど使いませんが、合致するfile2の行をそのまま出力するわけじゃないので、列区切りが空白1つになります。詳しくはman joinを。

投稿2022/02/20 13:00

otn

総合スコア84555

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2022/02/20 13:05 編集

あと、 > 強制終了と出てきてしまいます。 実際のメッセージは何でしょうか?
aufheben

2022/02/20 13:21

ubuntuで日本語設定なのですが、本当にそのまま"強制終了"と出てきます
otn

2022/02/20 13:30

それは何らかの監視ツールが動いてkill -9されてますね。自分の管理しているOSでしょうか?
guest

0

ベストアンサー

大量データに強いかはわかりませんが join コマンドなどどうでしょう。
両ファイルともソート済みであることが前提です。

$ join file1 file2 0000000001 aaa 0000000002 bbb 0000000004 ddd 0000000007 ggg 0000000008 eee 0000000010 iii

また本当にメモリ不足なのでしょうか。bash なら ulimit コマンドなどで制限かかっていないか確認してはどうでしょうか。

[追記]
こういうテキスト処理がよくあるのなら、コマンドを使ってあれこれ悩むより、Python 等でかんたんなスクリプトを組めるようにした方がよいのではと思います。
下記は file1 の分 (index_dict) しかメモリに持たないので、省メモリかと思います。

#!/usr/bin/env python3 index_dict = {} with open('file1', 'r') as f: for line in f: line = line.rstrip() index_dict[line]='' with open('file2', 'r') as f2: for line in f2: line = line.rstrip() arr = line.split(' ') if arr[0] in index_dict: print(line)

投稿2022/02/20 12:37

編集2022/02/20 13:03
68user

総合スコア2005

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問