固定数のパターン発生を含む行フィルタリング

固定数のパターン発生を含む行フィルタリング

ファイルがあると仮定

foo bar cat dog
foo foo cat bar
bar foo foo foo

fooたとえば、数字が次の場合、特定の回数だけ発生する行を見つけるためにどのようにgrepできますか?1サンプルファイルの最初の行だけを印刷する必要がありますか?

答え1

$ grep 'foo' file | grep -v 'foo.*foo'

最初にあるすべての行を選択してから、あるfooすべての行を削除し、その行内の他の行をfoo削​​除します。foo

すべての行に1つ以上の行が含まれている場合foo(例のように)、最初の行をスキップできますgrep

grep正確にどうすればいいですか?窒素文字列が表示されますか? 」: grep少なくとも以下を含む行の場合窒素一致した後の行の削除N+1(またはそれ以上)一致します。

答え2

一般的な場合 - 正確な行のみを印刷窒素awk'を使用してgsub()番号を返すことができます。置換を実行し、存在しない場合は行を印刷します。要件を満たしています。たとえば、正確に3回表示される行を印刷します。

 awk '{l=$0;t=gsub(/foo/,"",l)}t==3' infile

別の方法sed

sed 's/foo/&/3   
t x
: k
d
: x
s/foo/&/4
t k' infile

これは3番目の項目を自分で置き換えようとし、失敗した場合は行を削除しますd。成功すると、: x4番目のアイテムを独自に置き換えようとします。成功した場合(3つ以上が表示: kされることを意味)(ラインも削除されるように)に分岐し、そうでなければ何も行いません(ラインを自動的に印刷することを除く)。 ..)


例の特定のケース(一度だけ表示される行)には、次のものを使用することもできます。

sed '/foo/!d;/foo.*foo/d' infile

または同様のもの:

pcregrep '^(?:(?!foo).)*foo((?:(?!foo).)*)$' infile

答え3

grep -c計算に使用:

while read line; do [[ $(echo $line | sed 's/ /\n/g' | grep -c foo) == 2 ]] && echo "$line"; done < file.txt

答え4

別のオプションはを使用することですperl。たとえば、一致をリストコンテキストにプッシュし、スカラーコンテキストでテストします。

perl -ne 'my $count = () = $_ =~ /foo/g; print if $count == 1' file

あるいは、明示的なスカラー変数はありません。

perl -ne 'print if ( () = $_ =~ /foo/g ) == 1' file

このアプローチは、目的の異なる数の一致がある行を返すように簡単に一般化されています。

例を見る文字列内の一致するアイテムの数を計算するためのPerlのショートカットはありますか?

関連情報