Confronto tra due stringhe in Bash


22

Ho il seguente ifblocco nel mio script bash:

if [ ${PACKAGENAME} -eq kakadu-v6_4-00902C ]; then
  echo "successfully entered if block!!"
fi

L'esecuzione dello script non sta entrando nel mio ifblocco anche se $PACKAGENAMEè uguale a kakadu-v6_4-00902C. Che cosa sto facendo di sbagliato?


9
-eqè vero per i numeri interi, si desidera verificare una stringa o regex ( ==o =~): mywiki.wooledge.org/BashGuide/TestsAndConditionals
jasonwryan

Grazie jasonwryandarò un'occhiata a questa risorsa!
DemiSheep,

Risposte:


31

-eq è un operatore aritmetico, che confronta due numeri.

Utilizzare =(portatile / standard sh) =~o ==invece.

Usa anche le virgolette, perché se ${PACKAGENAME}contiene uno spazio bianco o un carattere jolly, verrà suddiviso in più argomenti, il che fa sì che vengano [visualizzati più argomenti del desiderato. Vedi qui un elenco di insidie ​​comuni di bash.

if [ "${PACKAGENAME}" = 'kakadu-v6_4-00902C' ]; then
    echo "successfully entered if block!!"
fi

Vedi man bash, cerca ( /) per CONDITIONAL EXPRESSIONS.


1
Ah! Grazie! Ha funzionato! Sono ovviamente un novellino in questo. Sono grato per il tuo aiuto!
DemiSheep,

2
Hai dato un'occhiata a tldp.org/LDP/Bash-Beginners-Guide/html ? È una guida bash molto bella e ti aiuterà con esempi ed esami :).
polimero

1
Grazie polymdarò un'occhiata, grazie per la risorsa! Aprirò quella scheda accanto alla mia guida VI. :)
DemiSheep,

4
Tra parentesi doppie, nessuna suddivisione delle parole viene eseguita, quindi [[ $PACKAGENAME == "kakadu..." ]]va bene.
Glenn Jackman,

4
@glennjackman Attenzione però che anche all'interno doppie parentesi quadre, è necessario doppie virgolette attorno espansioni variabili sul lato destro della =, ==e !=, perché quel lato è un modello, non una stringa. Ad esempio, foo='*'; [[ whatever = $foo ]]è vero.
Gilles 'SO- smetti di essere malvagio' il

6

Sostituisci -eqcon == così il tuo blocco if sarebbe questo: -

if [ ${PACKAGENAME} == kakadu-v6_4-00902C ]; then

        echo "successfully entered if block!!"

fi

5
Non dimenticare di citare! Dai
polym

@polym hey grazie, ma ho appena dato la versione minimalista che funzionava;): D.
Beginer,

4

Un altro modo è quello di negarli:

: ${PACKAGENAME:?'$PACKAGENAME variable is empty!'} #emits error and exits
[ -z "${PACKAGENAME#kakadu-v6_4-00902C}" ] || { #if var - str not empty do block
    echo '$PACKAGENAME is not kakadu-v6_4-00902C' 
    exit 1
} >&2

Le prime prove sopra blocchi se "$PACKAGENAME"ha alcun valore, e, se non esce con errore ed echi ?'this'}a stderr. Se la sua shell padre esiste ancora, il test è passato e successivamente verifica se rimuovendo la stringa 'kakadu ...' dalla variabile si ottiene una -zstringa vuota. In caso contrario, emette nuovamente un errore ed esce dalla shell. Se a questo punto la tua shell esiste ancora dopo l'esecuzione del blocco, altrimenti non lo è.

Probabilmente questo genere di cose è meglio implementato in una funzione. Piace:

argeq() ( i= : ${2?^MERR: not enough parameters!} #$#>=2 || quit w/ err ^M == \r
    z() { return $((${#1}>0)) ; } #return 1 if ${#1}>0 else 0
    until z "${2+?}" $((i=i+1)) #until $2 is not set...
    do  ! z "$1" && z "${1#"$2"}" || #$1 != '' && $1 - $2 == '' or...
        exit $((i${1:++1})) #exit $? == failed arg count
    shift ; done #shift away one param ; continue loop
)

Con quella funzione puoi fornire tutti gli argomenti che il tuo sistema permetterà. Se fornisci meno di 2, verrà restituito 1 ed emette un messaggio a stderr. Se si forniscono 2 o più argomenti, verranno trattati tutti come stringhe e verrà restituito 0 se tutti sono identici e non null, verrà restituito il numero dell'argomento che per primo non supera il controllo.

Nel tuo caso può essere usato come:

{   
    PACKAGENAME='kakadu-v6_4-00902C'
    argeq "$PACKAGENAME" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C == $PACKAGENAME" ||
        echo failure
    ! argeq "${PACKAGENAME#*-}" kakadu-v6_4-00902C &&
        echo "kakadu-v6_4-00902C != ${PACKAGENAME#*-}" ||
        echo failure
}

###OUTPUT###
kakadu-v6_4-00902C == kakadu-v6_4-00902C
kakadu-v6_4-00902C != v6_4-00902C

Per dimostrare ulteriormente scriverò un'altra funzione:

aeqecho() { i=$((i+1)) #inc for line#
    argeq "$@" && echo "$i : yay" || #allswell or
    ! e=$? ${2+:} return || #save $?; ! exclusive || to drop ERRs
    echo "$i : shite - arg$e failed" #report failure
}

DEMO:

{  i= s=string
   aeqecho $s #1
   aeqecho $s $s #2
   aeqecho "$s $s" #3
   aeqecho "$s $s" "${s} string" #4
   aeqecho "${s}1" $s string #5
   aeqecho "" "" "" #6
   aeqecho "" "$s" $s #7
   aeqecho 1 "${s#$s}1" $((2-1)) #8                     
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s stng #9  
   aeqecho $s $s $s $s $s $s $s $s $s $s $s $s string #10
}  

PRODUZIONE:

ERR: not enough parameters!
2 : yay
ERR: not enough parameters!
4 : yay
5 : shite - arg2 failed
6 : shite - arg1 failed
7 : shite - arg1 failed
8 : yay
9 : shite - arg13 failed
10 : yay
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.