Número de elementos / palavras em uma variável de matriz de shell

2

Analisei a questão Como contar número de palavras de String usando o shell no SO, o que explica como contar palavras dentro de uma variável.

Mas isso só conta uma palavra dentro da minha variável, então não tenho ideia de como corrigi-la.

Eu tenho as seguintes variáveis:

vmfarm1=(host1.com host2.com host3.com host4.com )
maximus=(host11.com host 12.com host 13.com)
firefly=(host5.com)

Eu preciso encontrar uma maneira de contar todos os nomes de host em um número dentro das variáveis.

Depois disso, o número dentro do que foi contado deve ser usado como uma variável nessa linha.

Eu tentei:

echo "$input" | wc -w
printf ' \n|/4.vmfarm1 ' >>  textfile.txt

Eu tenho que escrever o 4 acima por mim para o número e eu preciso que seja feito automaticamente, é por isso que eu preciso de uma variável.

    
por TheSebM8 15.05.2018 / 12:37

5 respostas

7

Dado um array arr , seu comprimento (número de elementos) é dado por ${#arr[@]} .

Usando isso com sua matriz vmfarm1 :

printf ' \n|/%d.vmfarm1 ' "${#vmfarm1[@]}" >>textfile.txt
    
por 15.05.2018 / 12:44
8

Para imprimir o número de elementos em uma variável de matriz em vários shells com suporte a matriz:

  • csh / tcsh / zsh / rc / es / akanga : echo $#array
  • ksh ¹ / bash ¹ / zsh : echo "${#array[@]}"
  • fish : count $array
  • yash : echo "${array[#]}"
  • Cascas Bourne / POSIX (onde a única matriz é "$@" ): echo "$#"

Agora, para o número de palavras delimitadas por espaço em branco em todos os elementos de uma variável de matriz, é nesse local que você pode usar wc -w , mas precisa fornecer o conteúdo de todos os elementos separados por pelo menos um espaço em branco, por exemplo, com:

printf '%s\n' $array:q | wc -w        # csh/tcsh
printf '%s\n' "${array[@]}" | wc -w   # ksh/bash/zsh/yash
printf '%s\n' $array | wc -w          # fish/zsh/rc/es/akanga
printf '%s\n' "$@" | wc -w            # Bourne/POSIX

Ou você pode dividir os elementos em mais palavras delimitadas por espaços em branco e contá-las no próprio shell.

  • csh / tcsh (dividido em SPC / TAB / NL)

    (set noglob; set tmp=($array); echo $#tmp)
    
  • ksh / bash / yash ( $IFS divisão, SPC / TAB / NL por padrão)

    (set -o noglob; set -- ${array[@]}; echo "$#")
    
  • zsh ( $IFS divisão, SPC / TAB / NL / NUL por padrão)

    echo ${#${=array}}
    
  • rc / es ( $ifs divisão):

    tmp = '{echo $array}
    echo $#tmp
    
  • fish (conta todas as sequências de caracteres que não são espaços em branco (de acordo com o PCRE)):

    count (string match -ar -- '\S+' $array)
    
  • Bourne / POSIX ( $IFS splitting):

    (set -f; set -- $@; echo "$#")
    

¹ observe que, dado que as matrizes ksh / bash são esparsas e têm índices que começam em 0 em vez de 1 em cada outro shell, esse número geralmente não será o mesmo que o índice máximo no array

    
por 15.05.2018 / 12:48
3

No Bash e no ksh, expandir um array como se fosse uma variável de string normal, fornece o primeiro elemento do array. Ou seja, $somearray é o mesmo que ${somearray[0]} . (*)

Então,

somearray=(foo bar doo)
echo "$somearray"
echo "$somearray" | wc -w

imprime foo e 1 , pois foo é apenas uma palavra. Se você tivesse somearray=("foo bar doo" "acdc abba") , então o wc mostraria três palavras.

Você precisará usar "${somearray[@]}" para expandir todos os elementos da matriz como palavras de shell distintas (argumentos) ou "${somearray[*]}" para expandi-las como uma única palavra de shell, associada a espaços (**)

Em qualquer caso, observe que o número de elementos em uma matriz e o número de palavras (no sentido wc -w ou da linguagem humana) não são os mesmos, veja abaixo. Use "${#somearray[@]}" para obter o número de elementos na matriz.

somearray=("foo bar doo" "acdc abba")
echo "${#somearray[@]}"                # 2 elements, that contain
echo "${somearray[@]}" | wc -w         # 5 whitespace separated words in total

(*) ignorando matrizes esparsas e associativas por enquanto.

(**) assumindo o padrão IFS .

    
por 15.05.2018 / 12:56
2

vmfarm1, maximus e firefly não são apenas variáveis, são matrizes.

Use a sintaxe adequada: ${#vmfarm1[@]} é o número de entradas na sua matriz.

    
por 15.05.2018 / 12:45
0

Isso pode não ser inteligente, mas acho que você pode obter o número de hosts na matriz.

vmfarm1=(host1.com host2.com host3.com host4.com)
#maximus=(host11.com host12.com host13.com)
#firefly(host5.com)
COUNT=0

for i in ${vmfarm1[@]};
do
    HOSTCOUNT='echo $i |wc -l'
    COUNT=$((COUNT + HOSTCOUNT))
done

printf "vmfarm1:%2d\n" $COUNT

Obrigado

    
por 15.05.2018 / 16:51

Tags