Die folgende Bash-Syntax überprüft, ob param
nicht leer ist:
[[ ! -z $param ]]
Zum Beispiel:
param=""
[[ ! -z $param ]] && echo "I am not zero"
Keine Ausgabe und es ist in Ordnung.
Wenn param
aber bis auf ein (oder mehrere) Leerzeichen leer ist, ist der Fall anders:
param=" " # one space
[[ ! -z $param ]] && echo "I am not zero"
"Ich bin nicht Null" wird ausgegeben.
Wie kann ich den Test ändern, um Variablen, die nur Leerzeichen enthalten, als leer zu betrachten?
bash
shell
shell-script
string
maihabunash
quelle
quelle
man test
:-z STRING - the length of STRING is zero
. Wenn Sie alle Leerzeichen entfernen möchten$param
, verwenden Sie${param// /}
trim()
in * nix integrierte einfache Funktion? So viele verschiedene Hacks, um etwas so Einfaches zu erreichen ...[[ ! -z $param ]]
gleichbedeutend ist mittest ! -z $param
.Antworten:
Beachten Sie zunächst, dass der
-z
Test explizit für Folgendes bestimmt ist:Das heißt, eine Zeichenfolge, die nur Leerzeichen enthält, sollte unter nicht wahr sein
-z
, da sie eine Länge ungleich Null hat.Was Sie wollen, ist, die Leerzeichen aus der Variablen mit der Musterersetzungsparameter-Erweiterung zu entfernen :
Dies erweitert die
param
Variable und ersetzt alle Übereinstimmungen des Musters(ein einzelnes Leerzeichen) durch nichts, sodass eine Zeichenfolge, die nur Leerzeichen enthält, zu einer leeren Zeichenfolge erweitert wird.
Das Wesentliche an der Funktionsweise ist, dass
${var/pattern/string}
das erste Spielpattern
mit dem längsten ersetzt wirdstring
. Wennpattern
mit/
(wie oben) begonnen wird, werden alle Übereinstimmungen ersetzt. Da die Ersetzung leer ist, können wir das Finale/
und denstring
Wert weglassen :Danach müssen wir
${param// }
alle Leerzeichen löschen.Beachten
ksh
Sie , dass die Syntax , obwohl sie in (woher sie stammt)zsh
und vorhandenbash
ist, nicht POSIX ist und nicht insh
Skripten verwendet werden sollte.quelle
sed
Sie sie sagten ... nurecho
die Variable, die sie sagten ...${var/pattern/string}
sollte es dann nicht[[ -z ${param/ /} ]]
mit dem Abstand zwischen den Schrägstrichen sein, um das Muster und nichts danach zu sein, um die Zeichenfolge zu sein?[[ -z "${param// }" ]]
sieht sicher so aus, als ob daspattern
leer und dasreplacement string
ein einzelnes Leerzeichen ist. AH! Ich sehe es jetzt, daif pattern begins with a slash
ich diesen Teil verpasst habe. Das Muster ist also/
und die Zeichenfolge ist weggelassen und daher leer. Vielen Dank.Die einfache Möglichkeit, zu überprüfen, ob eine Zeichenfolge nur Zeichen in einem autorisierten Satz enthält, besteht darin, zu prüfen, ob nicht autorisierte Zeichen vorhanden sind. Anstatt also zu testen, ob die Zeichenfolge nur Leerzeichen enthält, sollten Sie testen, ob die Zeichenfolge andere Zeichen als Leerzeichen enthält. In bash, ksh oder zsh:
"Besteht nur aus Leerzeichen" schließt den Fall einer leeren (oder nicht gesetzten) Variablen ein.
Möglicherweise möchten Sie nach Whitespace-Zeichen suchen. Verwenden
[[ $param = *[^[:space:]]* ]]
Sie diese[[ $param = *[$' \t\n']* ]]
Option , um Gebietsschemaeinstellungen oder eine explizite Liste von Leerzeichen zu verwenden, auf die Sie testen möchten, z. B. um Leerzeichen, Tabulatoren oder Zeilenumbrüche zu testen.Das Abgleichen einer Zeichenfolge mit einem Muster mit
=
inside[[ … ]]
ist eine ksh-Erweiterung (auch in bash und zsh vorhanden). In jedem Bourne / POSIX-Stil können Sie dascase
Konstrukt verwenden, um eine Zeichenfolge mit einem Muster abzugleichen. Beachten Sie, dass Standard-Shell-Muster verwendet werden!
, um einen Zeichensatz zu negieren, anstatt^
wie in den meisten regulären Ausdruckssyntaxen.Zum Testen auf Leerzeichen ist die
$'…'
Syntax spezifisch für ksh / bash / zsh. Sie können diese Zeichen buchstäblich in Ihr Skript einfügen (beachten Sie, dass eine neue Zeile in Anführungszeichen stehen muss, da Backslash + Newline zu nichts erweitert werden) oder sie generieren, zquelle
${var?not set}
, wenn Sie diesen Test bestehen und überleben, würde dies sicherstellen, dass eine Variable, die mit Ihrer übereinstimmt,*)
case
eine endgültige Wirkung hat antworte zum Beispiel.[[ $param = *[!\ ]* ]]
inmksh
.POSIXly:
So unterscheiden Sie zwischen leer , nicht leer , leer und nicht gesetzt :
[:blank:]
ist für Zeichen mit horizontalem Abstand (Leerzeichen und Tabulator in ASCII, aber wahrscheinlich sind noch einige in Ihrem Gebietsschema vorhanden; einige Systeme enthalten das nicht unterbrechende Leerzeichen (sofern verfügbar), andere nicht). Wenn Sie auch Zeichen mit vertikalem Abstand (z. B. Zeilenvorschub oder Formularvorschub) verwenden möchten, ersetzen Sie diese[:blank:]
durch[:space:]
.quelle
zsh
Scheint ein Problem damit zu haben[![:blank:]]
, es:b
ist ein ungültiger Modifikator. Insh
undksh
emulieren, es Ereignis nicht gefunden für[
var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac'
ist für mich ok. Das nicht gefundene Ereignis ist nur für interaktive Shells gedacht.:b
ungültige Modifikator ist etwas seltsam.sh
istbash
aufgebaut mit--enable-xpg-echo-default
und--enable-strict-posix-default
um Unix - konform (welches beinhaltet sein zumecho '\t'
Ausgeben eines TAB).Der einzige verbleibende Grund, ein Shell-Skript anstelle eines Skripts in einer guten Skriptsprache zu schreiben , ist, wenn extreme Portabilität ein vorrangiges Anliegen ist. Das Erbe
/bin/sh
ist die einzige Sache , die Sie sicher sein können , die Sie haben, aber Perl zum Beispiel ist eher wahrscheinlich verfügbar Cross-Plattform als Bash sein. Schreiben Sie daher niemals Shell-Skripte, die Funktionen verwenden, die nicht wirklich universell sind - und denken Sie daran, dass mehrere proprietäre Unix-Anbieter ihre Shell-Umgebung vor POSIX.1-2001 eingefroren haben .Es gibt eine tragbare Möglichkeit, diesen Test durchzuführen, aber Sie müssen Folgendes verwenden
tr
:(Der Standardwert von
$IFS
ist günstigerweise ein Leerzeichen, ein Tabulator und eine neue Zeile.)(Das
printf
eingebaute System ist selbst leicht zu transportieren, aber es ist viel einfacher, sich darauf zu verlassen, als herauszufinden, welche Varianteecho
Sie haben.)quelle
case
.case
Glob zu schreiben , um eine Zeichenfolge zu erkennen, die entweder leer ist oder nur Leerzeichen enthält . (Mit einem regulären Ausdruck wäre es einfach, aber ercase
führt keine regulären Ausdrücke aus. Das Konstrukt in Ihrer Antwort funktioniert nicht, wenn Sie sich für Zeilenumbrüche interessieren.)case $param in *[![:space:]]*) …
. Wenn Sie nachIFS
Zeichen suchen möchten , können Sie das Muster verwenden*[$IFS]*
.<space><tab><newline>
am Anfang explizit auf und berühren es dann nie wieder. Ich dachte, das wäre eine Ablenkung..profile
die von vielen Borowski-Muscheln ausgeführt wurden. Natürlich[$IFS]
wird nicht getan, was beabsichtigt war, wennIFS
bestimmte nicht standardmäßige Werte (leer (oder nicht gesetzt), enthaltend]
, beginnend mit!
oder^
) vorliegen .quelle
Um zu testen, ob die Variable leer ist oder Leerzeichen enthält, können Sie auch diesen Code verwenden:
quelle
:
.name=aaaa
dann diesen Befehl ausführen,echo ${name:?variable is empty}
er gibt den Wert des Variablennamens aus und jetzt diesen Befehl,echo ${name1:?variable is empty}
er gibt -sh: name1 aus: Variable ist leerecho ${name:?variable is empty}
wird entweder als$name
Nicht-Null-Wert ausgewertet oder die Shell wird beendet. So aus dem gleichen Grund Sie nicht tun ,prompt > $randomvar
weder sollten Sie${var?}
- wenn ein Befehl gibt es dort, ist es wahrscheinlich zu laufen gehen - und Sie wissen nicht , was es ist. Eine interaktive Shell muss nicht beendet werden. Wenn Sie dennoch einige Tests sehen möchten, gibt es hier viele . . Dieser ist nicht ganz so lang ...Um zu testen, ob eine Variable nicht gesetzt ist, leer ist (einen Nullwert hat) oder nur Leerzeichen enthält:
Erläuterung:
${param%%[! ]*}
entfernt sich vom ersten Nichtraum bis zum Ende.-z
, wird ein Echo ausgegebenempty
.Das obige ist POSIX-kompatibel und kann in allen Bourne-Nachkommen ausgeführt werden.
Wenn Sie dies auch auf Registerkarten ausweiten möchten, fügen Sie eine explizite Registerkarte hinzu:
oder verwenden Sie eine Variable mit den Zeichen, die Sie entfernen müssen:
oder Sie können einen POSIX "Zeichenklassenausdruck" verwenden (Leerzeichen bedeutet Leerzeichen und Tabulator):
Aber das wird in mksh, lksh und posh scheitern.
quelle
Versuche dies:
quelle