Porównaj łańcuch używając powłoki sh


197

Używam powłoki SH i próbuję porównać ciąg z wartością zmiennej, ale ifwarunek jest zawsze wykonywany na true. Czemu?

Oto kod:

Sourcesystem="ABC"

if [ "$Sourcesystem" -eq 'XYZ' ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

echo Sourcesystem Value is  $Sourcesystem ;

Nawet to nie działa:

Sourcesystem="ABC"

if [ 'XYZ' -eq "$Sourcesystem" ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

echo Sourcesystem Value is  $Sourcesystem ;

Po drugie, czy możemy dopasować to do NULL lub pustego ciągu?


Po pierwsze w powłoce Bourne'a nie potrzebujesz dodatkowego ';' Kiedy testuję uruchamiając skrypt w powłoce Bourne'a, warunek if jest fałszywy. Najpierw pojawi się ostrzeżenie: [: ABC: oczekiwano wyrażenia typu integer. Wynik to: „System źródeł NIE jest dopasowany do ABC”. Jak komentują inni, -eq jest używane do porównań całkowitych. Użyj pojedynczego znaku równości do porównania ciągów w powłoce Bourne'a (#! / Bin / sh). Twoja powłoka powinna cię poprawić w pierwszej kolejności.
Kemin Zhou

6
Głosowanie za ponownym otwarciem. Cytowane dupki dotyczą powłoki bash, a nie anemicznej powłoki sh, która czasami jest powłoką Posix lub Dash.
jww

1
Zgoda i głosowanie. shi bashmają taki sam związek jak Ci C++. Nawet jeśli kod napisany dla pierwszego jest ważny w drugim, odpowiedzi dla drugiego nie można ufać, że zadziałają w pierwszym.
btilly

Odpowiedzi:


290

Do =porównania ciągów należy użyć operatora:

Sourcesystem="ABC"

if [ "$Sourcesystem" = "XYZ" ]; then 
    echo "Sourcesystem Matched" 
else
    echo "Sourcesystem is NOT Matched $Sourcesystem"  
fi;

man testmówi, że używasz -zdo dopasowania do pustych ciągów.


2
Nie trzeba cytować ABCani XYZ.
ceving

29
Jeśli zmienna może zawierać spacje, konieczne jest cytowanie.
William Everett

1
Poprawiono przykład, aby ta część była bardziej przejrzysta @WilliamEverett.
Per Lundberg


36

eq służy do porównywania liczb całkowitych, zamiast tego użyj równego `` = '', przykład:

if [ 'AAA' = 'ABC' ];
then 
    echo "the same" 
else 
    echo "not the same"
fi

powodzenia


Uwaga: jeśli porównujesz zmienne, upewnij się, że używasz, "$VAR"a nie tylko$VAR
Sridhar Sarnobat

22

Miałem ten sam problem, zrób to

if [ 'xyz' = 'abc' ];
then
echo "match"
fi

Zwróć uwagę na spacje. W tym przypadku ważne jest, aby użyć spacji przed i po =znaku.

Sprawdź „ Inne operatory porównania ”.


1
w Dockerfile / bin / sh: 1: [: =: nieoczekiwany operator
holms

10

-eqjest operatorem porównania powłoki do porównywania liczb całkowitych. Aby porównać ciągi, musisz użyć =.


5

-eqjest matematycznym operatorem porównania. Nigdy nie używałem go do porównywania ciągów, polegania na ==i !=do porównań .

if [ 'XYZ' == 'ABC' ]; then   # Double equal to will work in Linux but not on HPUX boxes it should be if [ 'XYZ' = 'ABC' ] which will work on both
  echo "Match"
else
  echo "No Match"
fi

18
Zauważ, że operator ==nie działa na każdej powłoce. =jest prawidłowym operatorem do porównywania ciągów, a ==czasami jest synonimem.
Omer Dagan

3

Spośród 4 powłok, które przetestowałem, ABC -eq XYZwe testwbudowanej funkcji zshi ksh. Wyrażenie ma wartość false under /usr/bin/testi wbudowane dla dashi bash. W kshi zsh, łańcuchy są konwertowane na wartości liczbowe i są równe, ponieważ oba są równe 0. IMO, zachowanie poleceń wbudowanych dla kshi zshjest niepoprawne, ale specyfikacja dla testjest w tym przypadku niejednoznaczna.


1
Dzięki za test. Dlatego popularna jest powłoka Bourne'a.
Kemin Zhou

zsh wyraźnie wyświetla : wyrażenie całkowite oczekiwane po użyciu [ lub wbudowanego testu . Może wymuszasz [[], co ocenia oba jako 0, ponieważ łańcuchy nie są znaczącymi liczbami całkowitymi.
code933k

@ code933k Która wersja? Nie zdziwiłbym się, gdyby zachowanie się zmieniło.
William Pursell

@WilliamPursell zsh 5.7.1
code933k
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.