GNU/Linux >> Linux の 問題 >  >> Ubuntu

パイプでつながれた一連のGrepステートメントを1つのGrepステートメントに組み合わせるにはどうすればよいですか?

一連のgrepステートメントを組み合わせる方法があるかどうかを知りたいのですが、その効果は、一致する式を「または」ではなく「および」式にすることです。

以下のデモ:

./script  
     From one grep statement, I want output like this
a b c

     not like this
a
c
a b
a b c
a b c d

聞くのは台本を見てください。

 #!/bin/bash
 string="a
 b
 c
 d
 a b
 a b c
 a b c d"

 echo -e "\t From one grep statement I want output like this"
 echo "$string" |
 grep a |grep c |grep -v d #Correct output but pipes three grep statements

 echo -e "\n\tNot like this"
 echo "$string" |
 grep -e'a' -e'c' -e-v'd' #One grep statement but matching expressions are "or" versus "and"

承認された回答:

フィルタを変換することはできませんgrep a | grep c | grep -v d 単一の単純なgrep 。複雑で効果のない方法しかありません。その結果、パフォーマンスが低下し、式の意味がわかりにくくなります。

3つのグループの単一コマンドの組み合わせ

単一のコマンドを実行したいだけの場合は、awkを使用できます。 これは正規表現でも機能し、論理演算子と組み合わせることができます。フィルタに相当するものは次のとおりです。

awk '/a/ && /c/ && $0 !~ /d/'

ほとんどの場合、単一のコマンドへのパイプを単純化する理由はないと思います。ただし、組み合わせによって、より高速になる可能性のある非常に単純なgrep式が得られる場合を除きます(以下の結果を参照)。

Unixライクなシステムは、パイプを使用し、さまざまなユーティリティを相互に接続するように設計されています。パイプ通信は可能な限り最も効果的ではありませんが、ほとんどの場合それで十分です。現在、ほとんどの新しいコンピューターには複数のCPUコアが搭載されているため、パイプを使用するだけで「自然に」CPUの並列化を利用できます。

元のフィルターは非常にうまく機能し、多くの場合awk 単一のコアでも、ソリューションは少し遅くなります。

パフォーマンスの比較

簡単なプログラムを使用して、200 000 000行のランダムテストファイルを生成しました。各行には、文字aからのランダムな組み合わせとして4文字が含まれています。 、bc およびd 。ファイルには1GBがあります。テスト中、キャッシュに完全にロードされたため、ディスク操作がパフォーマンス測定に影響を与えることはありませんでした。テストはIntelデュアルコアで実行されました。

単一のgrep

$ time ( grep -E '^[^d]*a[^d]*c[^d]*$|^[^d]*c[^d]*a[^d]*$' testfile >/dev/null )
real    3m2.752s
user    3m2.411s
sys 0m0.252s

シングルawk

$ time ( awk '/a/ && /c/ && $0 !~ /d/' testfile >/dev/null )
real    0m54.088s
user    0m53.755s
sys 0m0.304s

元の3つのグレープがパイプされました

$ time ( grep a testfile | grep c | grep -v d >/dev/null )
real    0m28.794s
user    0m52.715s
sys 0m1.072s

ハイブリッド–ポジティブグレップの組み合わせ、ネガティブパイプ

$ time ( grep -E 'a.*c|c.*a' testfile | grep -v d >/dev/null )
real    0m15.838s
user    0m24.998s
sys 0m0.676s

ここでは、単一のgrep 複雑な表現のために非常に遅いです。 3つのグループの元のパイプは、並列化が良好なため、かなり高速です。並列化なし(シングルコア)では、元のパイプはawkよりもわずかに高速に実行されます これは、単一のプロセスとして並列化されていません。 Awkとgrepはおそらく同じ正規表現コードを使用しており、2つのソリューションのロジックは類似しています。

関連:11.10は何年間サポートされていますか?

明確な勝者は、2つの正のグループを組み合わせ、負のグループをパイプに残すハイブリッドです。 |の正規表現のようです パフォーマンスの低下はありません。


Ubuntu
  1. ファイル内の複数行パターンを検索するにはどうすればよいですか?

  2. 2 つの ar 静的ライブラリを 1 つにマージする方法は?

  3. Linuxでgrepを使用してファイル名だけを表示するにはどうすればよいですか?

  1. 複数のインターネット接続を1つにマージする方法は?

  2. 1つのディレクトリを下に移動する方法は?

  3. 複数のファイルを1つのgzファイルにgzipする方法は?

  1. Lxcコンテナにログインする方法は?

  2. ディレクトリを grep -R から除外するにはどうすればよいですか?

  3. 複数行の出力を 1 行に連結する方法は?