grepを使って単語が3回現れる行を見つけるには?

grepを使って単語が3回現れる行を見つけるには?

どんな単語でも含まれている行を3回探したいです。これを行うには、このコマンドを使用する方が良いと思いますgrep

これが私の試みです。

grep '\(.*\)\{3\}' myfile.txt

答え1

標準単語定義を使用してください。

  • GNU grep,3つ以上発生回数どんな言葉でも

    grep -E '(\W|^)(\w+)\W(.*\<\2\>){2}' file
    

  • GNU grep,わずか3発生回数どんな言葉でも

    grep -E '(\W|^)(\w+)\W(.*\<\2\>){2}' file | grep -Ev '(\W|^)(\w+)\W(.*\<\2\>){3}'
    

  • POSIX awk,わずか3~の出現どんな言葉でも

    awk -F '[^_[:alnum:]]+' '{           # Field separator is non-word sequences
        split("", cnt)                   # Delete array cnt
        for (i=1; i<=NF; i++) cnt[$i]++  # Count number of occurrences of each word
        for (i in cnt) {
            if (cnt[i]==3) {             # If a word appears exactly 3 times
                print                    # Print the line
                break
            }
        }
    }' file
    

    ~のため3つ以上そのような場合==はに変更してください>=

    等しいゴルフボールの単一ライン:

    awk -F '[^_[:alnum:]]+' '{split("",c);for(i=1;i<=NF;i++)c[$i]++;for(i in c)if(c[i]==3){print;next;}}' file
    

  • GNU Awk、3回だけ登場言葉ab

    gawk 'gsub(/\<ab\>/,"&")==3' file
    

    ~のため3つ以上そのような場合==はに変更してください>=


読む距離

答え2

このように?

egrep '(\<.+\>).+\<\1\>.+\<\1\>'
  • egrep(またはgrep -E)有効拡張正規表現、これは逆参照に必要です。
  • \<.+\>少なくとも1文字を含むすべての単語と一致します。
    • \<respは\>単語の境界と一致します(試行では単語の境界をまったく考慮していません)。
    • .+1つ以上の文字シーケンスと一致します(試行では、次.*のシーケンス一致を使用しました)。若いまたはもっと文字! )
  • 逆参照を使用して、一致するシーケンスが2番目(\1)と3番目(\1再)であることを確認します。
    • 一致の間に1つ以上の文字()シーケンスを許可するため、.+「foo bar foo dorbs foo godly」が一致します(「foo」という単語が3回表示されます)。
    • 隣接する単語(「foo foo foo」など)のみを一致させるには、次のように使用します[[:space:]]+

答え3

あなたの質問は、その行の単語が3回以上存在する場合はその行を印刷し、そうでなければ破棄するという意味であると仮定します。awkより読みやすくカスタマイズ可能なソリューションに使用します。

awk -F '\\W+' '{
    delete c; for (i=1;i<=NF;i++) if (length($i) && ++c[$i]==3) {print; next}
}' file

これは、各行で発生する回数を計算するすべてのフィールドのループです。どの単語でも3回到達すると、その行が印刷されます。削除配列し、次の行に移動します。また、カウントの空白のフィールドに印刷されないように、フィールド長のテストがあります。

-Fここでは、さまざまなフィールド区切り記号および/または多くのフィールド区切り文字を追加することで、「単語」の意味を簡単にカスタマイズできます(標準BREおよびEREがサポートされています)。上記の単語区切り記号は、および_[:alnum:]またはawk -F '\\W+'一致awk -F '[^_[:alnum:]]+'する単語の境界に似た文字を除くすべての文字ですgrep

人間の言語では、文字を除くすべてのような他の単語の境界が欲しいかもしれません。たとえば、awk -F '[^[:alpha:]]+'文字と数字を除外したり、下線だけawk -F '[^[:alnum:]]+'でなく単語にダッシュを使用したりしますawk -F '[^-_[:alnum:]]+'

設定しないと、-F空白文字のみが使用されます。

答え4


  • GNU sed拡張正規表現モードでは、-E1行に正確に3回繰り返されるすべての単語を検出します。

$ r1='.*\<\1\>'
$ r2=$r1$r1 r3=$r2$r1
$ sed -Ee "
    /\<(\w+)\>$r2/! d
    /\<(\w+)\>$r3/d
" file

  • Perlはハッシュを使用して単語をキーとして保存し、現在の行の数を値として保存します。
$ perl -lne 'my %h;
    $h{$_}++ for /\w+/g;
    print if grep { $_ == 3 } values %h;
' file

関連情報