まず、次のコマンドを実行しています。
実行されたコマンド:
/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status
コマンドの出力は次のとおりです。
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower
grep 'follower' | wc -l
「follower」という単語を使用してgrepし、その単語の総数()を印刷したいと思います。
ここで直面する問題は、コマンドの出力を「コマンドが見つかりません」が発生する変数に入れることができないことです。
-bash-4.2$ cat zookeeper.sh
#!/bin/bash
ZK_STATUS = ` /app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status `
ABC = $ZK_STATUS | grep 'follower' | wc -l
echo $ABC
出力:
-bash-4.2$ ./zookeeper.sh
ZooKeeper JMX enabled by default
Using config: /app/zookeeper/zookeeper-3.4.10/bin/../conf/zoo.cfg
./zookeeper.sh: line 2: ZK_STATUS: command not found
./zookeeper.sh: line 4: ABC: command not found
0
答え1
=
エラーは、割り当ての前後にスペースがあるために発生します。これはシェルスクリプトのバグです。を使用し
var=value
、使用しないでくださいvar = value
。それ以外の場合、シェルはvar
- というプログラムを実行しようとし、command not found
エラーメッセージが表示されます。使用する必要がありますコマンドの置き換えコマンドの出力を変数として取得します。例えば
ZK_STATUS=$(/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status)
grep
-c
一致する行数を数えるオプションがあるので、wc -l
そうする必要はありません。ZK_STATUS=$(/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status) ABC=$(printf '%s' "$ZK_STATUS" | grep -c follower)
またはもっと直接的に、
ABC=$(/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status | grep -c follower)
単語が複数回表示される行数を計算する代わりに、個々の項目を計算するには
follower
使用できませんgrep -c
。代わりに、次のようにしてください。
ABC=$(printf '%s' "$ZK_STATUS" | grep -o follower | wc -l)
grep -o
各一致は、独自の行に印刷されます。wc -l
次に、この行を計算します。
答え2
GNUgrep
または互換性があり、指定された空でない文字列に改行またはNUL文字が含まれていない場合:
string=follower
この文字列を含むいくつかの出力の行数を計算するには、次のようにしますcmd
。
count=$(
cmd | grep -cFe "$string"
)
この文字列が重ならない回数を数えるには、次のようにします。
count=$(
cmd | grep -oFe "$string" | wc -l
)
did
可能な重複発生回数(例:dididid
2回ではなく3回出現することを考慮):
count=$(
cmd | grep -Poe "(?=\Q$string\E)." | wc -l
)
(ここでも$string
含まれていないとします\E
。)
$string
全体を探したい場合言葉、たとえば、follower
またはfollowers
に含まれない場合は、上記のgrepコマンドにこのオプションを追加followership
できます。-w
効果的にfollower
文字、数字、または下線(いわゆる単語文字)。計算を防ぐには、anti-follower
手動で除外する必要があります。
count=$(
cmd | grep -Poe "(?<![\w-])\Q$string\E(?![\w-])" | wc -l
)
しかし、ここであなたの質問は基本的なシェル構文についてです。
シェル変数にコマンドの出力(末尾の改行を除く)を保存するには、次のようにします。
variable=$(cmd)
=
(古い構文を避けるために両側にスペースはありませんvariable=`cmd`
。)
上記のコマンドで指定されているように、変数の内容と改行文字を印刷するには、次のようにしますgrep
。
printf '%s\n' "$variable" | grep ...
(を使用しないでくださいecho
。リストコンテキストでパラメータ拡張を引用することを忘れないでください。)
zshで演算子を借りたbashや他のシェルでは、次のことも<<<
できます。
<<< "$variable" grep ...
とにかく、変数に複数の文字列が含まれていることを確認することが目的の場合は、次のようにする必要があります(標準シェル構文を使用)。
case $variable in
(*"$string"*) echo variable contains the string;;
(*) echo It does not;;
esac
(ここには$string
改行文字を含めることができます)。
または、次の出力で確認してくださいcmd
。
if
cmd | grep -qFe "$string"
then
echo cmd output contains the string
else
echo it does not
fi
答え3
次のコマンドで目的の出力を取得できます
/app/zookeeper/zookeeper-3.4.10/bin/zkServer.sh status \
| awk '{print gsub("follower",$0)}'
「follower」という言葉が何回現れるかを示します。この例では、出力が1行であると仮定します。
答え4
(GNU)awkでRSをNR-1
計算したい単語に設定し、最後に印刷します。
cmd | awk -vRS='follower' 'END{print NR-1}'