Sprawdź, czy łańcuch nie jest pusty ani spacji w skrypcie powłoki

93

Próbuję uruchomić następujący skrypt powłoki, który ma sprawdzić, czy łańcuch nie jest ani spacją, ani pustym. Jednak otrzymuję te same dane wyjściowe dla wszystkich 3 wymienionych ciągów. Próbowałem również użyć składni "[[", ale bezskutecznie.

Oto mój kod:

str="Hello World"
str2=" "
str3=""

if [ ! -z "$str" -a "$str"!=" " ]; then
        echo "Str is not null or space"
fi

if [ ! -z "$str2" -a "$str2"!=" " ]; then
        echo "Str2 is not null or space"
fi

if [ ! -z "$str3" -a "$str3"!=" " ]; then
        echo "Str3 is not null or space"
fi

Otrzymuję następujący wynik:

# ./checkCond.sh 
Str is not null or space
Str2 is not null or space
Shubhanshu Mishra
źródło
Czy w skryptach powłoki puste ciągi są nazywane ciągami zerowymi?
Josiah Yoder

Odpowiedzi:

124

Potrzebujesz miejsca po obu stronach !=. Zmień kod na:

str="Hello World"
str2=" "
str3=""

if [ ! -z "$str" -a "$str" != " " ]; then
        echo "Str is not null or space"
fi

if [ ! -z "$str2" -a "$str2" != " " ]; then
        echo "Str2 is not null or space"
fi

if [ ! -z "$str3" -a "$str3" != " " ]; then
        echo "Str3 is not null or space"
fi
dogbane
źródło
Wielkie dzięki, działa. Ale zastanawiam się, dlaczego zadanie nie używa spacji, podczas gdy porównanie tak.
Shubhanshu Mishra
5
^^ To jest składnia. Pierwsze słowo w linii poleceń to polecenie, a kolejne to argumenty. var=value [command [args]]to składnia, w której zmiennej przypisywana jest wartość. dla porównania, [( /usr/bin/[) jest poleceniem i wymaga, aby var1,! = & var2 były 3 oddzielnymi argumentami. zmienna1! = zmienna2 to pojedynczy argument.
anishsane
63

Do sprawdzania pustego łańcucha w powłoce

if [ "$str" == "" ];then
   echo NULL
fi

LUB

if [ ! "$str" ];then
   echo NULL
fi
RajeshKashyap
źródło
9
Operator równości w powłoce to =. Jest ==to nieprzenośny hack wymyślony przez autorów powłoki, aby zepsuć umysły młodych programistów.
Jens
17

Jeśli chcesz sprawdzić jakąkolwiek ilość białych znaków, a nie tylko pojedynczą spację, możesz to zrobić:

Aby usunąć ciąg z dodatkowych białych znaków (również warunkuje białe znaki w środku do jednej spacji):

trimmed=`echo -- $original`

W --gwarantuje, że jeśli $originalzawiera przełączniki rozumiane przez echo, będą nadal uważane za normalne argumenty mają być powtórzone. Również ważne jest, aby nie stawiać ""wokół $originallub przestrzenie nie zostaną usunięte.

Następnie możesz po prostu sprawdzić, czy $trimmedjest pusty.

[ -z "$trimmed" ] && echo "empty!"
hyde
źródło
3
W powłoce burne kończę z „-” jako wartością przyciętą.
Sridhar Sarnobat
Według tego posta , echo nie interpretuje - oznacza koniec opcji. W mojej powłoce Bash otrzymuję ten sam wynik, co Sridhar Sarnobat
Mr.C
9

Kolejny szybki test na to, że ciąg ma coś w sobie, ale spację.

if [[ -n "${str// /}" ]]; then
    echo "It is not empty!"
fi

„-n” oznacza ciąg o niezerowej długości.

Następnie pierwsze dwa ukośniki oznaczają wszystkie poniższe, w naszym przypadku. Następnie po trzecim ukośniku następuje zastępczy (pusty) ciąg i zamykany jest za pomocą „}”. Zwróć uwagę na różnicę w stosunku do zwykłej składni wyrażeń regularnych.

Możesz przeczytać więcej o manipulowaniu ciągami znaków w skryptach powłoki bash tutaj .

elomage
źródło
to nie [[ -n "$1" ]]to samo co [[ ! -z "$1" "]]?
Alexander Mills,
@AlexanderMills masz rację, użycie -n sprawi, że będzie trochę krótszy. Właśnie odpowiednio zaktualizowałem odpowiedź.
elomage,
6

Aby sprawdzić, czy ciąg jest pusty lub zawiera tylko spacje, możesz użyć:

shopt -s extglob  # more powerful pattern matching

if [ -n "${str##+([[:space:]])}" ]; then
    echo '$str is not null or space'
fi

Zobacz Rozszerzanie parametrów powłoki i dopasowywanie wzorców w podręczniku Bash.

Eugene Yarmash
źródło
1
[ $(echo $variable_to_test | sed s/\n// | sed s/\ //) == "" ] && echo "String is empty"

Usunięcie wszystkich nowych linii i spacji z ciągu spowoduje zredukowanie pustego do niczego, co można przetestować i zastosować

Surowa Shandilya
źródło