grepを使用して、特定の文字を含むX文字列を含むすべての行を見つけます。

grepを使用して、特定の文字を含むX文字列を含むすべての行を見つけます。

したがって、最後に単語がある一連の数字を含むテキストファイルがあります。

123456 126 2 12456 1256 4 46 12346 123456 4 56 word
24 245 1234 356 12346 6 3 346 245 5 12346 12356 word

8つ以上の文字列(1つ、6つ、またはその両方を含む)を含むすべての行を見つけたいです。したがって、最初の行には、1、6、またはその両方を含む8つの文字列(スペースで区切られている)があるため、渡されます。 2番目には、1、6、またはその両方を含む7つの文字列のみがあります。

次の正規表現を試しましたが、逆追跡制限エラーが発生します。([0-9]*(1|6)[0-9]* .*){8,}

答え1

1正規表現を作成する代わりに、次のコードは最後のフィールドを除いてスペースで区切られたすべてのフィールドを繰り返し、またはが含まれている場合はカウンタをインクリメントします6。カウンタ値が8以上の場合、現在のレコードが出力されます。

awk '{ count = 0; for (i = 1; i < NF; ++i) count += ($i ~ "[16]") }; count >= 8' file

次のコードは同じことを行いますが、レコードを出力したい場合は計算を停止します。

awk '{ count = 0; for (i = 1; i < NF && count < 8; ++i) count += ($i ~ "[16]") }; count == 8' file

短い(読み取れない)行(カウンタが実行中です)。下に8)から:

awk '{c=8;for(i=1;i<NF&&c;++i)c-=$i~"[16]"}!c' file

答え2

パールの使用:

$ perl -ane 'print if (grep /[16]/, @F) >= 8' file.txt 
123456 126 2 12456 1256 4 46 12346 123456 4 56 word
  • -a各入力ラインを配列に自動的に分割します@F

  • -nPerlが次のように実行されるようにしますsed -n(つまり、各入力行を繰り返すが明示的に指示しない限り、何も印刷しません)。

  • -e次のパラメータは実行するスクリプトです。

  • スカラーコンテキストで使用されると、perlgrep()関数は一致の数を返します(一方、リストコンテキストでは一致のリストを返します)。つまり、配列内の一致する要素の数を計算します@F

    この機能は次のようになります。いいえ、同じです。コマンドgrepラインプログラム。perldoc -f grep詳細より。


ところで、一致するアイテムの数を印刷するには、次のようにします。

$ perl -ane '$x = grep /[16]/, @F; if ($x >= 8) {printf "%2i: %s", $x, $_}' /tmp/junk.txt 
 8: 123456 126 2 12456 1256 4 46 12346 123456 4 56 word

答え3

使用sed

$ sed -En 's/ ?[0-9]*[16][0-9]* /&/p8' input_file
123456 126 2 12456 1256 4 46 12346 123456 4 56 word

関連情報