30

どうすれば bash 変数 (空白で区切られたトークン) 内のトークンの数を知ることができますか? または少なくとも、それが 1 つであるか複数であるかを知るにはどうすればよいですか?

4

7 に答える 7

39

$# 展開は、変数/配列の要素数を示します。2.05 以降の bash バージョンを使用している場合は、次のことができます。

VAR='some string with words'
VAR=( $VAR )
echo ${#VAR[@]}

これにより、文字列が空白 (デフォルトの区切り文字) に沿って効果的に配列に分割され、配列のメンバーがカウントされます。

編集:

もちろん、これは変数を配列として再キャストします。それが望ましくない場合は、別の変数名を使用するか、変数を文字列に再キャストします。

VAR="${VAR[*]}"
于 2009-03-12T14:29:17.960 に答える
33

なぜ人々が複雑すぎるバシズムをいつも使っているのか、私には理解できません。ほとんどの場合、簡単でバシズムのない解決策があります。

howmany() { echo $#; }
myvar="I am your var"
howmany $myvar

これは、シェルに組み込まれているトークナイザーを使用するため、矛盾はありません。

関連する落とし穴の 1 つを次に示します。

myvar='*'
echo $myvar
echo "$myvar"
set -f
echo $myvar
echo "$myvar"

@guns の bash 配列を使用したソリューションにも同じ落とし穴があることに注意してください。

以下は、(おそらく)問題を回避するための非常に堅牢なバージョンです。

howmany() ( set -f; set -- $1; echo $# )

サブシェルを避けたい場合、事態は悪化し始めます

howmany() {
    case $- in *f*) set -- $1;; *) set -f; set -- $1; set +f;; esac
    echo $#
}

これら 2 つは引用符で使用する必要がありhowmany "one two three"ます。3

于 2012-08-11T20:55:26.307 に答える
14
set VAR='hello world'
echo $VAR | wc -w

確認方法は次のとおりです。

if [ `echo $VAR | wc -w` -gt 1 ] 
then
    echo "Hello"
fi
于 2009-03-12T14:25:31.510 に答える
1

カウントする:

sentence="This is a sentence, please count the words in me."
words="${sentence//[^\ ]} "
echo ${#words}

チェックする:

sentence1="Two words"
sentence2="One"
[[ "$sentence1" =~ [\ ] ]] && echo "sentence1 has more than one word"
[[ "$sentence2" =~ [\ ] ]] && echo "sentence2 has more than one word"
于 2011-11-03T23:37:10.843 に答える
1

堅牢で移植可能 shなソリューションについては、@JoSo の functions using を参照してくださいset -f

(「少なくとも 1 つの空白はありますか?」という質問に (のみ) 回答するための単純な bash のみのソリューション。注:awk以下のソリューションとは異なり、先頭と末尾の空白にも一致します。

 [[ $v =~ [[:space:]] ]] && echo "\$v has at least 1 whitespace char."

)

堅牢なawkベースの bash ソリューションを次に示します (外部ユーティリティの呼び出しにより効率が低下しますが、実際の多くのシナリオではおそらく問題にならないでしょう)。

# Functions - pass in a quoted variable reference as the only argument.
# Takes advantage of `awk` splitting each input line into individual tokens by
# whitespace; `NF` represents the number of tokens.
# `-v RS=$'\3'` ensures that even multiline input is treated as a single input 
# string.
countTokens() { awk -v RS=$'\3' '{print NF}' <<<"$1"; }
hasMultipleTokens() { awk -v RS=$'\3' '{if(NF>1) ec=0; else ec=1; exit ec}' <<<"$1"; }

# Example: Note the use of glob `*` to demonstrate that it is not 
# accidentally expanded.
v='I am *'

echo "\$v has $(countTokens "$v") token(s)."

if hasMultipleTokens "$v"; then
  echo "\$v has multiple tokens."
else
  echo "\$v has just 1 token."
fi
于 2014-02-02T04:42:05.403 に答える
-1

これがまさにあなたが意図したものかどうかはわかりませんが、

$#= bash スクリプトに渡される引数の数

それ以外の場合は、次のようなものを探している可能性がありますman wc

于 2009-03-12T14:23:59.190 に答える