BASH-文字列内の部分文字列の出現回数を数える


0

Bashを使用して文字列内の部分文字列の出現回数をカウントするにはどうすればよいですか?

例:

この部分文字列が何回か知りたい...

Bluetooth
         Soft blocked: no
         Hard blocked: no

...この文字列に出現しています...

0: asus-wlan: Wireless LAN
         Soft blocked: no
         Hard blocked: no
1: asus-bluetooth: Bluetooth
         Soft blocked: no
         Hard blocked: no
2: phy0: Wireless LAN
         Soft blocked: no
         Hard blocked: no
113: hci0: Bluetooth
         Soft blocked: no
         Hard blocked: no

注I: sed、grep、awkを使用していくつかの方法を試しました。スペースと複数行の文字列がある場合、何も機能しないようです。

注II:私はLinuxユーザーであり、Linuxディストリビューションで通常見られるもの以外のアプリケーション/ツールのインストールを伴わないソリューションを試みています。


重要:

以下の仮想的な例のようなものが欲しいです。この場合、2つのシェル変数(Bash)を使用します。

例:

STRING="0: asus-wlan: Wireless LAN
         Soft blocked: no
         Hard blocked: no
1: asus-bluetooth: Bluetooth
         Soft blocked: no
         Hard blocked: no
2: phy0: Wireless LAN
         Soft blocked: no
         Hard blocked: no
113: hci0: Bluetooth
         Soft blocked: no
         Hard blocked: no"

SUB_STRING="Bluetooth
         Soft blocked: no
         Hard blocked: no"

awk -v RS='\0' 'NR==FNR{str=$0; next} {print gsub(str,"")}' "$STRING" "$SUB_STRING"

注:説明のためだけにawkを使用しています!


プログラマ向けのSEサイトであるStack Overflowで、さらに役立つ情報が見つかるでしょう。また、UnixおよびLinux SEでさらにヘルプが見つかる可能性もあります。
juniorRubyist

回答:


2

でもっとうまくできるとawk思いますが、これは私が提供できる最高のものです。

grep -zo "Bluetooth\s*Soft blocked: no\s*Hard blocked: no" file_name | grep -c "Bluetooth"

-z作るgrep1行としてファイル全体を扱います。

-o行全体ではなく、文字列に一致した出力のみを書き込みます。
(この場合-z、whouldはファイル全体を意味します)

\s 空白文字と改行に一致します。

の2番目のインスタンスはgrep、最初のgrep呼び出しの出力で単語「Bluetooth」のみを検索します。

-cgrep自分自身にマッチする代わりに、マッチした正規表現のカウントを書き込みます。


@Iskustvoに感謝しますが、あなたの答えには問題があると思います。スペースの量を変更する文字列をエスケープする必要があり、さらに、このプロセスを自動化する機能が必要になります。それ以外は、シェル変数(Bash)を使用できるようにしたい(変更と私の質問を参照)!もっと説明しようと思います。たとえば、私のエントリが「ソフトブロック:no」または「ソフトブロック:no」で、値が「\ s * Softブロック:no」の場合、一致結果は入力された元の文字列のスペースとは無関係になります。ありがとう!= D
エドゥアルドルチオ

2
私はあなたが言っていることを理解しています、まあ、それのすべてではなく、その大部分。しかし、私はより良い答えを提供できるとは思わない。あなたのリクエストはgrepおよびsedツールを超えており、awk、perl、またはpythonのような動作を使用する必要があり、私はそれを支援することはできません。他の回答がすべての基準に一致することを願っています。
イスカスヴォ

あなたの貢献に感謝します!悪い英語(実際はポルトガル語を話す)でごめんなさい!= D
エドゥアルドルチオ

0

どのように一致させたいのか少しわかりません(上記のコメントの追加例では何も明らかにしません)が、ファイル内にネットワーク情報を含むstring文字列ブロックと、ファイル内に部分文字列ブロックを格納すると仮定しますsubstring

次のアプローチを使用すると、期待どおりの結果が得られます:2マッチ。

cat string | tr -s " " | tr '\n' '@' | grep -o "$(cat substring | tr -s " " | tr '\n' '@')" | wc -l

基本的に、両方の文字列は空白またはタブを無視して1行に凝縮され、改行をに変換し@ます。grep -o構文を使用して、-o見つかったパターンのすべての出現()を出力します。

ただし、この例で0回(完全一致)または2回(先頭に追加されたテキストを無視)に一致するかどうかは不明です。これは、Iskustvoここに投稿したものと非常によく似たソリューションです。私たちがあなたの意図を誤解したのでしょうか?

2次元のテキストフラグメントの一致をカウントしようとしている場合、ファジーgrepが必要になる可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.