AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 412933
Accepted
yael
yael
Asked: 2017-12-26 02:28:01 +0800 CST2017-12-26 02:28:01 +0800 CST 2017-12-26 02:28:01 +0800 CST

Como testar se os elementos da matriz são todos iguais no bash?

  • 772

A matriz a seguir representa o número de discos em cada máquina Linux

Cada array único inclui o número de discos em uma máquina Linux .

echo ${ARRAY_DISK_Quantity[*]}
4 4 4 4 2 4 4 4

qual é a maneira simples de identificar que todos os valores da matriz são iguais?

bom estado:

4 4 4 4 4 4 4 4

Estado ruim:

4 4 4 4 4 4 2 4

Estado ruim:

6 6 6 6 6 6 6 6 6 6 2 6 2
bash shell-script
  • 8 8 respostas
  • 14991 Views

8 respostas

  • Voted
  1. Best Answer
    cas
    2017-12-26T03:17:54+08:002017-12-26T03:17:54+08:00

    bash+ GNU sort+ grepsolução GNU:

    if [ "${#array[@]}" -gt 0 ] && [ $(printf "%s\000" "${array[@]}" | 
           LC_ALL=C sort -z -u |
           grep -z -c .) -eq 1 ] ; then
      echo ok
    else
      echo bad
    fi
    

    Explicação em inglês: se a classificação única dos elementos da matriz resultar em apenas um elemento, imprima "ok". Caso contrário, imprima "ruim".

    A matriz é impressa com bytes NUL separando cada elemento, canalizada para a classificação GNU (baseando-se nas opções -zaka --zero-terminatede -uaka --unique) e depois grep(usando as opções -zaka --null-datae -caka --count) para contar as linhas de saída.

    Ao contrário da minha versão anterior, não posso usar wcaqui porque requer linhas de entrada terminadas com uma nova linha ... e usar sedou trpara converter NULs em novas linhas após anular sorto propósito de usar separadores NUL. grep -cfaz um substituto razoável.


    Aqui está a mesma coisa reescrita como uma função:

    function count_unique() {
      local LC_ALL=C
    
      if [ "$#" -eq 0 ] ; then 
        echo 0
      else
        echo "$(printf "%s\000" "$@" |
                  sort --zero-terminated --unique |
                  grep --null-data --count .)"
      fi
    }
    
    
    
    ARRAY_DISK_Quantity=(4 4 4 4 2 4 4 4)
    
    if [ "$(count_unique "${ARRAY_DISK_Quantity[@]}")" -eq 1 ] ; then
      echo "ok"
    else
      echo "bad"
    fi
    
    • 12
  2. Stéphane Chazelas
    2017-12-26T03:50:14+08:002017-12-26T03:50:14+08:00

    Com zsh:

    if ((${#${(u)ARRAY_DISK_Quantity[@]}} == 1)); then
      echo OK
    else
      echo not OK
    fi
    

    Onde (u)está um sinalizador de expansão de parâmetro para expandir valores exclusivos . Portanto, estamos obtendo uma contagem dos valores únicos na matriz.

    Substitua == 1por <= 1se você deseja considerar que uma matriz vazia está OK.

    Com ksh93, você pode classificar o array e verificar se o primeiro elemento é igual ao último:

    set -s -- "${ARRAY_DISK_Quantity[@]}"
    if [ "$1" = "${@: -1}" ]; then
      echo OK
    else
      echo not OK
    fi
    

    Com ksh88 ou pdksh/mksh:

    set -s -- "${ARRAY_DISK_Quantity[@]}"
    if eval '[ "$1" = "${'"$#"'}" ]'; then
      echo OK
    else
      echo not OK
    fi
    

    Com bash, você provavelmente precisaria de um loop:

    unique_values() {
      typeset i
      for i do
        [ "$1" = "$i" ] || return 1
      done
      return 0
    }
    if unique_values "${ARRAY_DISK_Quantity[@]}"; then
      echo OK
    else
      echo not OK
    fi
    

    (funcionaria com todos os shells do tipo Bourne com suporte a array (ksh, zsh, bash, yash)).

    Observe que ele retorna OK para uma matriz vazia. Adicione um [ "$#" -gt 0 ] || returnno início da função se você não quiser isso.

    • 9
  3. RomanPerekhrest
    2017-12-26T02:45:08+08:002017-12-26T02:45:08+08:00

    bash+ awksolução:

    function get_status() {
        arr=("$@")    # get the array passed as argument
        if awk 'v && $1!=v{ exit 1 }{ v=$1 }' <(printf "%d\n" "${arr[@]}"); then 
            echo "status: Ok"
        else 
            echo "status: Bad"
        fi
    }
    

    Caso de teste nº 1:

    ARRAY_DISK_Quantity=(4 4 4 4 4 2 4 4)
    get_status "${ARRAY_DISK_Quantity[@]}"
    status: Bad
    

    Caso de teste nº 2:

    ARRAY_DISK_Quantity=(4 4 4 4 4 4 4 4)
    get_status "${ARRAY_DISK_Quantity[@]}"
    status: Ok
    
    • 4
  4. jesse_b
    2017-12-26T04:25:28+08:002017-12-26T04:25:28+08:00

    Eu tenho outra solução somente bash que também deve funcionar com strings:

    isarray.equal () {
        local placeholder="$1"
        local num=0
        while (( $# )); do
            if [[ "$1" != "$placeholder" ]]; then
                num=1
                echo 'Bad' && break
            fi
            shift
        done
        [[ "$num" -ne 1 ]] && echo 'Okay'
    }
    

    Demonstração:

    [root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(4 4 4 4 2 4 4 4)
    [root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
    Bad
    [root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(4 4 4 4 4 4 4 4)
    [root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
    Okay
    [root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(four four four four two four four four)
    [root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
    Bad
    [root@JBSTEST001 ~]# ARRAY_DISK_Quantity=(four four four four four four four four)
    [root@JBSTEST001 ~]# isarray.equal "${ARRAY_DISK_Quantity[@]}"
    Okay
    
    • 4
  5. Cyrus
    2017-12-26T08:02:37+08:002017-12-26T08:02:37+08:00

    Com bash e GNU grep:

    if grep -qE '^([0-9]+)( \1)*$' <<< "${ARRAY_DISK_Quantity[@]}"; then 
      echo "okay"
    else
      echo "not okay"
    fi
    
    • 2
  6. user267425
    2017-12-26T02:58:04+08:002017-12-26T02:58:04+08:00

    bash apenas solução (assumindo que aé ARRAY_DISK_Quantity)

    ttt=${a[0]}
    res=0
    for i in "${a[@]}"
    do 
        let res+=$(if [ "$ttt" -ne "$i" ]; then echo 1; else echo 0; fi);  
    done
    if [ "$res" -eq 0 ]
    then 
        echo "ok"
    else
        echo "bad"
    fi
    
    • 0
  7. Zombo
    2017-12-26T14:29:44+08:002017-12-26T14:29:44+08:00

    Aqui está o POSIX Awk:

    awk 'BEGIN {while (++z < ARGC) if (ARGV[z] != ARGV[1]) exit 1}' "${ARRAY_DISK_Quantity[@]}"
    
    • 0
  8. megengo
    2019-02-22T06:36:48+08:002019-02-22T06:36:48+08:00

    Use um loop for para comparar cada elemento do array com o próximo. Termine o loop uma iteração a menos que o comprimento da matriz para evitar comparar o último elemento com nada no final.

    for (( i=0; i<((${#array[@]}-1)); i++ )); do
        [ "${array[$i]}" != "${array[(($i+1))]}" ] && echo "Mismatch"
    done
    echo "Match"
    
    • 0

relate perguntas

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • MySQL Select com função IN () com array bash

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Matriz JSON para bash variáveis ​​usando jq

    • 4 respostas
  • Marko Smith

    A data pode formatar a hora atual para o fuso horário GMT? [duplicado]

    • 2 respostas
  • Marko Smith

    bash + lê variáveis ​​e valores do arquivo pelo script bash

    • 4 respostas
  • Marko Smith

    Como posso copiar um diretório e renomeá-lo no mesmo comando?

    • 4 respostas
  • Marko Smith

    conexão ssh. Conexão X11 rejeitada devido a autenticação incorreta

    • 3 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Marko Smith

    comando systemctl não funciona no RHEL 6

    • 3 respostas
  • Marko Smith

    rsync porta 22 e 873 uso

    • 2 respostas
  • Marko Smith

    snap /dev/loop em 100% de utilização -- sem espaço livre

    • 1 respostas
  • Marko Smith

    chave de impressão jq e valor para todos no subobjeto

    • 2 respostas
  • Martin Hope
    EHerman Matriz JSON para bash variáveis ​​usando jq 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux A data pode formatar a hora atual para o fuso horário GMT? [duplicado] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC Como posso copiar um diretório e renomeá-lo no mesmo comando? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve Como as permissões de arquivo funcionam para o usuário "root"? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey Como baixar o pacote não instalá-lo com o comando apt-get? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao Por que os diretórios /home, /usr, /var, etc. têm o mesmo número de inode (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg — o comando list-keys gera uid [ desconhecido ] depois de importar a chave privada para uma instalação limpa 2017-11-26 18:26:02 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve