Подтвердить что ты не робот

Количество токенов в переменной bash

как узнать количество токенов в переменной bash (токены, разделенные пробелами), или, по крайней мере, более или менее, или больше.

4b9b3361

Ответ 1

Расширение $# будет указывать количество элементов в переменной/массиве. Если вы работаете с версией bash, превышающей 2.05, или вы можете:

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

Это эффективно разделяет строку на массив по пробелу (который является разделителем по умолчанию), а затем подсчитывает элементы массива.

EDIT:

Конечно, это изменяет переменную как массив. Если вы этого не хотите, используйте другое имя переменной или верните переменную обратно в строку:

VAR="${VAR[*]}"

Ответ 2

Я не могу понять, почему люди постоянно используют эти сложнейшие базисы. Почти всегда есть прямолинейное решение без башизма.

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

Это использует токенизатор, встроенный в оболочку, поэтому нет расхождений.

Здесь есть одна взаимосвязь:

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

Обратите внимание, что решение из @guns с использованием массива bash имеет тот же пароль.

Ниже приведена (предположительно) супер-надежная версия для работы с gotcha:

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

Если мы хотим избежать подоболочки, все начинает становиться уродливым

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

Эти два должны использоваться с кавычками WITH, например. howmany "one two three" возвращает 3

Ответ 3

set VAR='hello world'
echo $VAR | wc -w

вот как вы можете проверить.

if [ `echo $VAR | wc -w` -gt 1 ] 
then
    echo "Hello"
fi

Ответ 4

Считать:

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"

Ответ 5

Не уверен, что это именно то, что вы имели в виду, но:

$#= Число аргументов, переданных в bash script

В противном случае вы можете найти что-то вроде man wc

Ответ 6

Простой метод:

$ VAR="a b c d"
$ set $VAR
$ echo $#
4

Ответ 7

Для надежного портативного решения sh см. @JoSo функции с помощью set -f.

(Простое bash -одное решение для ответа (только) вопроса "Есть ли хотя бы один пробел?", примечание: также будет соответствовать начальному и завершающему пробелу, в отличие от решения awk ниже:

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

)

Вот надежное решение bash на основе awk (менее эффективное из-за вызова внешней утилиты, но, вероятно, не будет иметь значения во многих реальных сценариях):

# 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