同じ行にパターンが表示される回数を計算します。

同じ行にパターンが表示される回数を計算します。

この問題はシェルスクリプトで解決する必要があります。以下の文字列の発生回数を数えていますが、abc私が望む答えは3です。

echo abcsdabcsdabc | grep -o abc  
abc  
abc  
abc  

-oオプションがないと仮定すると、どのように処理するgrep必要がありますか?

答え1

文字列は次の区切りフィールドで構成されていると思いますabc

$ echo abcsdabcsdabc | awk -F 'abc' '{ print (length > 0 ? NF - 1 : 0) }'
3

区切り文字の発生回数は、abc1 から区切り文字が区切られたフィールドの数を引いたものです。

$ echo abcsdabcsdabc | awk '{ n=0; while (sub("abc", "xxx")) n++; print n }'
3

abcその後、その行の部分文字列が置き換えられ、xxx完了した回数が計算され、その数が出力されます。n=0入力行が1行だけの場合は必要ありません。

gsub()の関数はawk置換回数を返すので、上記の内容は次のように単純化できます。

$ echo abcsdabcsdabc | awk '{ print gsub("abc", "xxx") }'
3

では、bashこのプログラムで行ったのと同じことができます。awksub()

string=abcsdabcsdabc

n=0
while [[ $string == *abc* ]]; do
    n=$(( n+1 ))
    string=${string/abc/xxx}  # replace first occurrence of "abc" with "xxx"
done
printf '%d\n' "$n"

whileこれは、上記の2番目のプログラムと同様に、inが見つからなくなるまでループを使用してin値の部分文字列を置き換えます。abc$stringxxxabc$stringawk

答え2

そしてawk

awk -- 'BEGIN{print gsub(ARGV[2], "&", ARGV[1])}' abcsdabcsdabc abc

パターン(ここでは)は拡張正規表現(/supported正規表現に似ています)abcとして扱われます。awkgrep -Eegrep

この構文を使用すると、トピックと正規表現に複数の行を含めることができます。私たちも避けるechoランダムデータをエクスポートできない場合のよくある質問

perl正規表現を使用してください(GNUに似ていますgrep -P):

perl -le 'print scalar (() = $ARGV[0] =~ m{$ARGV[1]}g)' -- abcsdabcsdabc abc

é(ただし、ロケールのエンコードによっては、引数はテキストとして解釈されません。たとえば、UTF-8ロケールで .引数を使用すると、1(文字)ではなく2(バイト)が報告されます。

を使用すると、zsh次のことができます。

occurrences() {
  set -o localoptions -o extendedglob

  local n=0
  : ${1//(#m)$2/$((++n))}
  echo $n
}

occurrences abcsdabcsdabc abc

ここで、2番目の引数(abc)は固定文字列として解釈されます。代わりに、$2拡張され$~2たzsh globパターン(拡張正規表現よりも広範な機能セットを持っていますが、構文は異なります)として解釈されます。

答え3

Raku(以前のPerl_6)の使用

~$ echo "abcsdabcsdabc" | raku -ne '.match("abc", :global).say;'
(「abc」 「abc」 「abc」)

一致は上に示されています(1行ずつ)。一致する項目の数(1行)は次のとおりです。

~$ echo "abcsdabcsdabc" | raku -ne '.match("abc", :global).elems.say;'
3

注::globalパラメータはに省略できます:g

HTH。

https://raku.org/

答え4

GNUの使用sed

echo abcsdabcsdabc | sed 's/abc/abc\n/g' | wc -w

関連情報