grepで大量の条件がある場合の対処方法
記事の更新日:2026/09/30 評価を加筆
1.概要
grepで抽出処理を良く実行します。条件が1個や2個ならば良いのですが、大量の条件がある場合にどうやって実現すると良いか悩みました。forのループで処理できるのはわかるのですが、効率が悪いので方式を検討しました。その内容を記述します。
条件が1つの場合: grep 0001 test.file
条件が2つの場合: grep -e 0001 -e 0002 test.file
条件が多数の場合: grep -e 0001 -e 0002 -e 0003 -e 0004 -e 0005 ... -e 1000 test.file
更に条件が多いと: Argument list too longとなってしまう
私の評価は以下の通りです。
(1) grepで多数の条件設定が必要な場合、grep -f オプションを利用する
(2) -f オプションを利用すると正規表現を利用することは難しい
(3) その理由は正規表現で冗長となり、メモリ利用料が増加、制限超えと思われる
(4) grep以外の手段を利用する。しかし、良い代替品は見つからない
2.詳細
(1) 普通のやり方
forのループを作成して、条件の文字列を作ります( cond.txt )。
条件文字列作成のforのループは文字列を検索しないので効率には影響しません。
-e 0001 -e 0002 -e 0003 -e 0004 -e 0005 ... -e 1000
調べたい対象ファイルをtest.fileとします。
COND=$(cat cond.txt)
grep ${COND} test.file
(2) grepで非常に大量の条件がある場合の対処方法
実際にgrepで大量のパラメータを設定してみると
エラーメッセージが、「Argument list too long」と表示されてしまいます。
調べてみるとエラーの条件が想定したものと異なりました。その内容を記述します。
(a) パラメータが長すぎる
STR="-e 100001 -e 100002 -e 100003 -e 100004 -e 100005 ... -e 300000"
を作成して、下記grepを実行すると「Argument list too long」のエラーとなりました。
grep ${SRT} test.txt > test.out
参考資料によるとパラメータの長さが1MBを超えたことが要因のようです。
この対策が下記(b)のケースと同じに見えるので、対処方法を見つけることが難しかった。
(b) test.txtが大きすぎる
test.txtが大きすぎるエラーには、test.txt程度のサイズでは起きることはありません。
しかし、参考資料に記載されているように検索対象が多すぎる場合も同じエラーになるようです。
「Argument list too long」のエラーメッセージと表示されて判別が難しいと思います。
検索対象が多すぎる場合は、参考資料に対処方法が記載されており、xargsを利用して分割します。
(3) grepで非常に大量の条件がある場合の抜本改善策
実際にgrepで大量のパラメータを設定して、下記エラーが発生しました。
「Argument list too long」のエラーへの対策に関して記述します。
grep --help を参照すると下記指定ができます。
-f, --file=FILE take PATTERNS from FILE
そこで、pattern.datを以下のように作成します。
100001
100002
100003
100004
100005
...
300000
grep -f pattern.dat test.txt > test.out
を実行すると「Argument list too long」のエラーは解消されます。
3.考察
(1) 正規表現の利用
grepは正規表現が可能なので、少し調べてみました。
pattern.datを少し変えてみました。
^[0-9]*,100001
^[0-9]*,100002
...
^[0-9]*,300000
同じように実行すると途中でエラーとなります。
grep -f pattern.dat test.txt > test.out
調べてみるとメモリを使い切って、処理を中断していました。
-f で指定する場合は、正規表現を多数記述するのは難しいようです。
(2) CONDの長さに制限
CONDの長さに制限があると思ったので調べてみました。
getconf ARG_MAX
2097152
十分なサイズだと思いますが、実際に試験しようと思っています。
4.所見
パラメータを渡す方式はネットを探しても見つけることができずに困っていました。最後にhelpを読んで、実行できるかもしれないと感じて試したことです。helpに記載されていることが最後の解決策になるとは思いませんでした。
grepは抽出と除外にとても便利なツールです。しかし、データがが大量で複雑な場合には条件設定が複雑になり、問題となることを知りました。この問題を回避する手段を試すことを色々実施したので、何かの機会に役に立つと思っています。
コメント
コメントを投稿