Strings de duas matrizes distintas não correspondentes?

2

Estou tentando filtrar um array de outro array. Ou seja, estou tentando criar um terceiro array com uma não interseção lógica.

O melhor que posso dizer é que esse bloco de código nunca corresponde e found permanece baixo:

found=0
...

if [ "$flag" = "$filtered" ]; then
    found=1
fi

Eu tentei usar == com o mesmo resultado. Eu também tentei o truque X , mas isso também não funcionou (isso se aplica aqui?): if [ "X$flag" = "X$filtered" ] .

Estou restrito ao Bash 3. Estou usando o Bash porque sei disso. Estou restrito a 3 porque o script é executado no OS X também. Por causa do Bash 3, acho que estou perdendo muitas funções úteis, como o HashMaps.

Por que as strings não estão combinando?

Aqui está o trecho relevante. CXXFLAGS pode ser definido pelo usuário em seu ambiente. Estou tentando remover sinalizadores que testamos explicitamente em nosso script de teste, como -DDEBUG , -DNDEBUG e otimizações como -O0 e -O1 .

# Respect user's preferred flags, but filter the stuff we expliclty test
FILTERED_CXXFLAGS=("-DDEBUG", "-DNDEBUG", "-O0", "-O1", "-O2", "-O3", "-Os", "-Og")
# Additional CXXFLAGS we did not filter
RETAINED_CXXFLAGS=("")

if [ ! -z "CXXFLAGS" ]; then
    TEMP_CXXFLAGS=$(echo "$CXXFLAGS" | sed 's/\([[:blank:]]*=[[:blank:]]*\)/=/g')
    IFS=' ' read -r -a TEMP_ARRAY <<< "$TEMP_CXXFLAGS"

    for flag in "${TEMP_ARRAY[@]}"
    do
        echo "Flag: $flag"
        found=0
        for filtered in "${FILTERED_CXXFLAGS[@]}"
        do
            echo "Filtered: $filtered"
            if [ "$flag" = "$filtered" ]; then
                echo "Found: $flag"
                found=1
            fi
        done
        echo "Found: $found"
        if [ "$found" -eq "0" ]; then
            echo "Retaining $flag"
            RETAINED_CXXFLAGS+=($temp)
        else
            echo "Discarding $temp"
        fi
    done
fi

Aqui está um rastreamento com o echo's no lugar. Os dados do teste foram simplesmente export CXXFLAGS="-DNDEBUG -g2 -O3 -mfpu=neon"

Flag: -DNDEBUG
Filtered: -DDEBUG,
Filtered: -DNDEBUG,
Filtered: -O0,
Filtered: -O1,
Filtered: -O2,
Filtered: -O3,
Filtered: -Os,
Filtered: -Og
Found: 0
Retaining -DNDEBUG
Flag: -g2
Filtered: -DDEBUG,
Filtered: -DNDEBUG,
Filtered: -O0,
Filtered: -O1,
Filtered: -O2,
Filtered: -O3,
Filtered: -Os,
Filtered: -Og
Found: 0
Retaining -g2
Flag: -O3
Filtered: -DDEBUG,
Filtered: -DNDEBUG,
Filtered: -O0,
Filtered: -O1,
Filtered: -O2,
Filtered: -O3,
Filtered: -Os,
Filtered: -Og
Found: 0
Retaining -O3
Flag: -mfpu=neon
Filtered: -DDEBUG,
Filtered: -DNDEBUG,
Filtered: -O0,
Filtered: -O1,
Filtered: -O2,
Filtered: -O3,
Filtered: -Os,
Filtered: -Og
Found: 0
Retaining -mfpu=neon
    
por jww 03.06.2016 / 22:58

1 resposta

3

Eles não correspondem porque FILTERED_CXXFLAGS tem vírgulas e ${TEMP_ARRAY[@]} não:

Flag: -DNDEBUG
Filtered: -DDEBUG,
Filtered: -DNDEBUG,

Se as vírgulas estiverem lá, substitua:

if [ "$flag" = "$filtered" ]; then

com:

if [ "$flag" = "${filtered%%,}" ]; then

Como alternativa, se as vírgulas não devem estar lá, a questão é:

FILTERED_CXXFLAGS=("-DDEBUG", "-DNDEBUG", "-O0", "-O1", "-O2", "-O3", "-Os", "-Og")

Pode-se usar declare -p para ver qual valor bash deu a uma variável:

$ declare -p FILTERED_CXXFLAGS
declare -a FILTERED_CXXFLAGS='([0]="-DDEBUG," [1]="-DNDEBUG," [2]="-O0," [3]="-O1," [4]="-O2," [5]="-O3," [6]="-Os," [7]="-Og")'

Pode-se ver que as vírgulas estão incluídas no valor de cada elemento. Embora muitos idiomas requeiram que elementos da matriz sejam separados por vírgulas, o shell Unix não. Em vez disso, trata-os como parte do valor dos elementos da matriz. Assim, substitua a definição acima por:

FILTERED_CXXFLAGS=("-DDEBUG" "-DNDEBUG" "-O0" "-O1" "-O2" "-O3" "-Os" "-Og")
    
por 03.06.2016 / 23:06