通常、grep
パターンに一致するすべての行が出力されます。パターンと何度も一致する行を見つけたいです。たとえば、私の検索パターンが「foo」の場合:
foo bar # Would not be matched
foo foo bar # Would be matched
bar foofoo # Would be matched
foobarfoo # Would be matched
grep
検索パターンに一致する項目が複数含まれている行のみを検索できるようにする方法はありますか?
答え1
grep -E "(foo.*){2}" file
これは、ファイルまたは出力の各行で少なくとも2回一致し、提供できる最小一致数です。
答え2
一致するすべての行を一致させるにはどの文字列を2回:
grep '\(.\{1,\}\).*\1'
以下を変更して、一致する長さを変更できます1,
。
seq 10000 | grep '\(.\{2,\}\).*\1'
これは基本正規表現(着替える)なのでPOSIX互換grep
。
貪欲でない正規表現(すべての場所でサポートされていない)を使用するように正規表現を変換すると、一致が速くなることはありません。
grep -E '(..*?).*?\1'
グラフは、各n個の数字の100行(〜行の長さ)での非欲張りな実行の有無による実行時間(秒)を示しています。
greedy() {
a=`seq $1`;
yes $a | head -n 100 | grep '\(.\{1,\}\).*\1' | LC_ALL=C wc;
}
nongreedy() {
a=`seq $1`;
yes $a | head -n 100 | grep -E '(..*?).*?\1' | LC_ALL=C wc;
}
export -f greedy
export -f nongreedy
parallel --jl my.log {2} {1}000 {2} ::: {1..100} ::: greedy nongreedy
答え3
grep "foo.*foo" file.txt
foo
これにより、2回以上発生した行のみが返されます。一度だけ現れる行は返されません。
上記のコードはほとんどの場合、引用符なしで動作しますが、ディレクトリ内のglobと一致するファイル名を持つ他の場合(たとえば)は正規表現を引用する必要があるため、二重引用符をfoo.barfoo
含めるように回答を編集しました。