
したがって、最後に単語がある一連の数字を含むテキストファイルがあります。
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
。-n
Perlが次のように実行されるようにしますsed -n
(つまり、各入力行を繰り返すが明示的に指示しない限り、何も印刷しません)。-e
次のパラメータは実行するスクリプトです。スカラーコンテキストで使用されると、perl
grep()
関数は一致の数を返します(一方、リストコンテキストでは一致のリストを返します)。つまり、配列内の一致する要素の数を計算します@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