2015-06-15 12 views
7

Próbuję porównać dwa ciągi w skrypcie bash i otrzymuję bardzo dziwne wyniki.Porównanie bash stringów

if [[ "010" < "01." ]]; then echo "Wrong"; else echo "OK"; fi 
if [[ "010" < "01.0" ]]; then echo "Wrong"; else echo "OK"; fi 
if [ "010" \< "01." ]; then echo "Wrong"; else echo "OK"; fi 
if [ "010" \< "01.0" ]; then echo "Wrong"; else echo "OK"; fi 

Czytając dokumentację wydawało się, że [[ < ]] i [ \< ] powinien działać tak samo, ale tak nie jest. Wydaje się, że [[ < ]] działa nieprawidłowo, gdy łańcuchy nie mają tej samej długości. Czy czegoś brakuje?

Edytuj: Spodziewany wynik to 4 x OK. Testowane na:

  • CentOS uwolnienia 6,4 (końcowe) - GNU Basha, wersja 4.1.2 (1) -release (x86_64-RedHat'cie Linux-gnu) (OK Wrong OK OK)
  • Ubuntu 14.04.2 LTS - GNU bash, wersja 4.3.11 (1) - wydanie (x86_64-pc-linux-gnu) (OK Wrong OK OK)
  • openSUSE 13.1 (butelka) (x86_64) - GNU bash, wersja 4.2.53 (1) -release (x86_64- suse-linux-gnu) (OK OK OK OK)
+3

mógłbyś dodać ou tput skryptu? – moffeltje

+2

Wszystko mi odpowiada ok. – 123

+0

Drugi mówi "źle dla mnie" na 'GNU bash, wersja 4.3.39'. – fedorqui

Odpowiedz

1

Oto dokumentacja z help test:

STRING1> STRING2

Prawda, jeśli sortuje łańcuch1 po łańcuch2 leksykograficznie.

Biorąc swój pierwszy if oświadczenie jako przykład:

if [[ "010" < "01." ]]; then echo "Wrong"; else echo "OK"; fi 

w bash ciąg "01." rodzaju leksykograficznie przed ciąg "010" (można sprawdzić w innych narzędzi, takich jak Microsoft Excel), a więc porównanie zwraca false. Dotyczy to wszystkich 4 porównań.

Należy pamiętać, że dodanie dodatkowego 0 do końcanie zmienia kolejności w porównaniu do "010", więc nadal otrzymujesz taki sam wynik.

+0

Jestem na bash 4.2.53 (opensuse13.1); get "OK, źle, OK, OK", więc on ma punkt ... –

+0

Jestem też na Bash 4.2.53 i otrzymuję OK dla wszystkich 4. To jest naprawdę dziwne –

+0

kiedy sortuję trzy wartości Otrzymuję: "01.", "010", "01.0" –

0

Przyczyną może być to, że począwszy od basha 4.1 operatory porównania stringów respektują ustawienia narodowe.

więc między dwoma systemami można mieć następującymi różnicami:

  1. różnych lokalizacjach - sprawdzić uruchamiając locale (o znaczeniu innym lokum ustawień patrz https://unix.stackexchange.com/a/87763/122478)
  2. nawet jeśli lokalizacje są takie same , shopt compat31 lub compat32 mogą być włączone (tryb kompatybilności bash 3.1 lub 3.2), co oznacza, że ​​porównania łańcuchów nie będą zgodne z ustawieniami regionalnymi - sprawdzenie po uruchomieniu shopt

Dalszy odczyt:

-1

Jeśli wan porównać całkowitą powinien to zrobić:

jeśli [[10 < 1]]; then echo "10 < 1"; else echo "10> 1"; fi 10> 1

Jeśli chcesz porównać unosić należy szukać w tym wątku: How to do float comparison in Bash?

Dla przykładu:

echo "10 < 1.0" | bc powrotu: 0

echo "10> 1,0" | BC retunr: 1

+0

Dobrze Jestem nieco zdezorientowany, gdy widzę tę odpowiedź jako niepoprawną próbka poleceń: mat @ lapdev001: ~ $ if [[11 <10]]; następnie echo "<"; else echo ">"; fi > mat @ lapdev001: ~ $ if [[11 <25]]; następnie echo "<"; else echo ">"; fi < I dla porównania ciągów: mat @ lapdev001: ~ $ if [["longstring"> "string"]]; następnie echo "<"; else echo ">"; fi > mat @ lapdev001: ~ $ if [["ciąg"> "ciąg"]]; następnie echo "<"; else echo ">"; fi > mat @ lapdev001: ~ $ if [["string"> "longstring"]]; następnie echo "<"; else echo ">"; fi < –