Como verificar o primeiro elemento em uma matriz

1

Eu tenho o seguinte Array Loop configurado. Ele simplesmente percorre uma string e verifica se cada item corresponde a uma letra e define algumas variáveis de acordo.

#!/usr/bin/env bash
IN="ItemName -a -b"

itemA=0
itemB=0
itemI=0

while IFS=' -' read -ra ARR; do
    for x in "${ARR[@]}"; do
        echo "x = $x"
        y=${x:0:1}
        echo "y = $y"
        case $y in
            "a") itemA=1 ;;
            "b") itemB=1 ;;
            "I") itemI=1 ;;
        esac
    done
done <<< "$IN"

echo "itemA is $itemA
echo "itemB is $itemB"
echo "itemI is $itemI" 

No entanto, para o primeiro elemento ("itemName"), preciso definir isso separadamente, para que ele não seja verificado como parte do resultado do caso. Idealmente eu quero acabar com:

itemName is ItemName
itemA is 1
itemB is 1
itemI is 0

Como posso verificar o primeiro elemento? Eu tentei

if [ ${ARR[0]} ] ; then
    itemName=$x
else
 . . . 
fi  

mas acabou sem nenhuma das variáveis configuradas.

    
por IGGt 10.12.2015 / 13:05

3 respostas

2

Não vejo por que você está usando um loop while . Solte o while e seus problemas desaparecerão:

#!/usr/bin/env bash
IN="ItemName -a -b"
itemA=0
itemB=0
itemI=0

## Read the array, no loop required
IFS=' -' read -ra ARR <<<"$IN"
## Save the 1st element as itemN
itemN=${ARR[0]}
## Remove itemN from the array
unset ARR[0]
## Now loop over the rest
for x in "${ARR[@]}"; do
    y=${x:0:1}
    case $y in
        "a") itemA=1 ;;
        "b") itemB=1 ;;
        "I") itemI=1 ;;
        esac
done

echo "itemN is $itemN"
echo "itemA is $itemA"
echo "itemB is $itemB"
echo "itemI is $itemI" 

Executando o script acima das impressões:

itemN is ItemName
itemA is 1
itemB is 1
itemI is 0
    
por 10.12.2015 / 16:19
0

Eu não sei se isso é necessariamente o melhor caminho, mas funciona:

#!/usr/bin/env bash
IN="ItemName -a -b"

itemName=0
itemA=0
itemB=0
itemI=0

while IFS=' -' read -ra ARR; do
    for x in "${ARR[@]:1:0}"; do
        itemName=$x
    done

    for x in "${ARR[@]:1}"; do
        y=${x:0:1}
        case $y in
            "a") itemA=1 ;;
            "b") itemB=1 ;;
            "I") itemI=1 ;;
        esac
    done
done <<< "$IN"

echo "itemName is $itemName"
echo "itemA is $itemA
echo "itemB is $itemB"
echo "itemI is $itemI" 

Basicamente, eu processei o Array duas vezes. Uma vez para obter apenas o primeiro item e, em seguida, novamente para obter todos os itens, exceto o primeiro item.

    
por 10.12.2015 / 15:40
0

Eu usaria mais matrizes. Essa resposta depende da versão 4 do bash para matrizes associativas.

IFS=' -' read -ra words <<<"$IN"
declare -A items

for i in "${words[@]}"; do
    [[ $i == "ItemName" ]] && continue
    items["${i:0:1}"]=1
done

for key in "${!items[@]}"; do
    echo "item $key is ${items[$key]}"
done
item a is 1
item b is 1

Se você precisar definir alguns valores padrão para a matriz de itens:

declare -A items=([a]=0 [b]=0 [c]=0)

Então você veria

item a is 1
item b is 1
item c is 0
    
por 10.12.2015 / 16:55