ファイルがあると仮定
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
。成功すると、: x
4番目のアイテムを独自に置き換えようとします。成功した場合(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
このアプローチは、目的の異なる数の一致がある行を返すように簡単に一般化されています。