2012-09-16 2 views
5

私はgrepやgrepのようなツールを探しています。これには、grep、egrep、awk、sed、またはマッチの検索に使用されるその他のツールが含まれますが、これに限定されません。しかし、私は残りの質問のためにそれをgrepと呼びます。高速なgrep/grep(回線番号のみ)?

私は、ファイルをgrepするための速い方法を探しています。また、一致するファイルをgrepし、行番号を返すのが最も速い方法を探しています。ライン。文法が複雑で複雑なものであれば、私は心配しないでください。プログラムの複雑さの中で使用するつもりはありません。

パターンを正規表現する必要がある場合は、このメソッドを使用して範囲を検索することもできます。だから、私は10未満のすべての数字を検索する必要がある場合は、commmandがデフォルトでそれをサポートしている場合、または正規表現にする必要がある場合、私は見つけることができる最も速い方法を探しています。

ありがとうございました。

編集

私が働いているファイルは非常に大きくなり、私のテストファイルは、最初の試合の後に停止するには1.9ギガバイト

答えて

5

KingsIndianはgrepの-mオプションでターゲットになっていますが、スピードが主な目標である場合はcutがこの特定の用途ではawkより速くなる場合があります。試してみてください。-f1引数は出力のみに最初のフィールドを、それを伝えながら-d:引数は、フィールド区切り文字としてコロンを使用するためにカット指示します

grep -n -m 1 regex file | cut -d: -f1 

+0

これは他のものとちょうど同じように機能しましたが、平均して数百ミリ秒で少し速く動作しました。私は私がgrep -n -m 10 regex fileをやることをいくつかスキップする必要があるかどうか推測しています。テール-5 | cut -d:-f1 – WojonsTech

+0

cutを使用する場合、タブをセパレータとしてどのように指定しますか? – Bulrush

+0

cutは、デフォルトで区切り記号としてタブを使用しているので、-d: – nullrevolution

3

です:

grep -n -m 1 str file | awk -F: '{print $1}' 

あなたは、引数の値を変更することができますmの値を異なる値に設定すると、多くの一致後に停止します。 awk部分は、行番号のみをキャプチャすることです。あなたはそのためtailを使用することができます

grep -n -m 5 str file | awk -F: '{print $1}' 

を編集:5つの試合の後に停止するには

。例えば、最初の5試合をスキップして、次の7を印刷:grep -n -m 12 str file| tail -7 | awk -F: '{print $1}'

+0

はかなりクールですあなたが知っている)最も遅い5倍以上速く、この操作であります最初のいくつかの結果をスキップして次の5を印刷して終了する方法がある場合は、それは私がこのプロジェクトで必要としていることですが、今のところすべてを出力することにも取り組んでいます。 – WojonsTech

+1

@WojonsTechはそれを編集しました。 –

+0

本当にかっこいいです。私はそんなことは考えていませんでした。私たちが求めているところでawkよりも速いものがあるかどうか知っていますか、grepを返すほうが速いのですか?awkに結果セットを強制的にループさせるよりも速いです。 – WojonsTech

1

私はこれが高速であるかどうかわからないんだけど、これが動作しているようです:

nl -b a "<filename>" | grep "<phrase>" | awk '{ print $1 }' 
+0

これはうまくいきますが、nlを使う代わりに、grep -nを使って行番号で出力を得ることができます。 – WojonsTech

1

あなたはGNU awkを用いたパターンマッチングを行うことができますし、単純に行番号をプリントアウト:値を仮定し

awk '/regex/ { print NR }' file.txt 

は、行が10未満の数字が含まれている場合は、行番号を見つけることができるスペースで区切られ、以下のとおりです。

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) print NR }' file.txt 

ただし、これは10未満の数字の各行の行番号を出力します。これは望ましくないと思われるかもしれません。あなたはsort -nにソート出力、パイプが必要な場合は

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (i in array) print i }' file.txt 

:したがって、各試合のために、複数の重複した行番号を削除するには、配列を使用することができます。より洗練されたソリューション(例:

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (j in array) sorted[k++]=j+0; n = asort(sorted); for (j=1; j<=n; j++) print sorted[j] }' file.txt 

EDIT:なし配管)との上記最後の三つawkコマンドのいずれにおいて

、単に11〜20包括的な結果を表示するif ($i >= 11 && $i <= 20)if ($i <= 10)を変更します。

+0

私は探していたものではありませんが、awkを使って解決するためのプログラム的な方法です。 – WojonsTech

+0

@WojonsTech:あなたのやりたいことを_exactly_で更新してください。私が理解しているところでは、正規表現を検索して行番号と一致する行を出力したいとします。おそらく私は後者についてはっきりしていなかったでしょう。この例では、 'awk '/ regex/{print NR、$ 0}' file.txt'を試してください。 HTH。 – Steve

+0

私はまた、それを使用するためのシステムhevery方法を探していた。私は人々がgrepとcutを使う場所を見てきましたが、awkがどのようにスタックしているのかわからないけど、かなり速く動いていますが、それはうまくいったのですが、結果を制限する最良の方法を探していますか? – WojonsTech

1

私はちょうどnonforking SED呼び出しでいくつかのテストを行い、幸運ではなかったが、私の$パターンは非常に最後の行の一部である1ギガバイトのテキストファイル、とここに参照のため番号:

(スポイラー: grepが、awkは-mがある

 
[email protected]:~$ ls -lh /dev/shm/test 
-rw-r--r-- 1 user user 979M Jul 8 09:50 /dev/shm/test 
 
[email protected]:~$ sed --version | head -n1 
GNU sed-Version 4.2.1 
[email protected]:~$ time sed -n "/$PATTERN/{=;q}" /dev/shm/test 
206558 

real 0m6.835s 
user 0m6.160s 
sys 0m0.648s 
 
[email protected]:~$ grep -V | head -n1 
grep (GNU grep) 2.14 
[email protected]:~$ time grep -n -m 1 "$PATTERN" /dev/shm/test | cut -d: -f1 
206558 

real 0m1.337s 
user 0m0.592s 
sys 0m0.736s 
 
[email protected]:~$ awk --version | head -n1 
GNU Awk 4.0.1 
[email protected]:~$ time awk "/$PATTERN/ { print NR }" /dev/shm/test 
206558 

real 0m7.176s 
user 0m6.356s 
sys 0m0.776s 

関連する問題